展锐A13 Camera Hal dispatch模块流程 --- 上

news2024/9/23 21:22:09

4月份就知道展锐A13的Camera Hal有大的变动,但是最近一直在做一个MTK的项目,没去看这个新增部分的流程。最近有时间,就把A13上Camera Hal新增的部分流程捋 了一下,过程是痛苦的,但是坚持一遍遍去读代码,在结合展锐的官方文档,思路就慢慢清晰了。
整个hal总共新增了两个模块,dispatch 和 lwp,我们先看dispatch模块,在看lwp模块,最后就可以将两个模块的流程串起来。

本篇文章先来说这几个文件,路径在: vendor\sprd\modules\libcamera\hal3_2v6\dispatch
在这里插入图片描述

文章目录

    • FrameDispatch
      • FrameDispatch.h
        • 1,DispatchFrameInfo :就是camera_frame_type 的一个封装
        • 2,Framelisten
        • 3,FrameProducer
        • 4,RangeListener
      • FrameDispatch.cpp:
        • 1,registerListener 与 removeListener
        • 2,threadLoop
    • FrameProcesser
      • FrameProcesser.h
      • FrameProcesser.cpp
        • 1,构造函数
        • 2,析构函数
        • 3,clearResource
        • 4,ps系列
        • 5,stream系列
        • 6,生命周期系列:producerInit、producerStart、producerStop
        • 7,pushBufferQueue 和 popOneBuffer
        • 8,委托给PolicyMgr处理的函数
    • FramePolicyMgr
      • FramePolicyMgr.h
        • 1,模板类:ThreadJobQueue
        • 2,结构体及指针函数
        • 3,policyFrameThread
        • 4,模板类 FramePolicy ,继承自FramePolicyBase
        • 5,FramePolicyMgr的声明
      • FramePolicyMgr.cpp
        • 1,内部类:class preLoaderPolicy
        • 2,FramePolicyMgr 的构造与析构
        • 3,match 系列
        • 4,mRequestInfo 集合数据的维护
        • 5,FramePolicyMgr::policyModulesLoadSelf
        • 6,FramePolicyMgr::policyModulesLoad
        • 7,FramePolicyMgr::policyModulesLoad

FrameDispatch

FrameDispatch.h

1,DispatchFrameInfo :就是camera_frame_type 的一个封装

FrameDisaptch.h 内部有4个类(这里说的类包括类和结构体哈)

typedef struct DispatchFrameInfo {
    DispatchFrameInfo () {
        memset(&queue_frame, 0, sizeof(struct camera_frame_type));
        FrameTrace = PROCESS;
    }
    enum trend {
        INVAIL,
        PROCESS,
        PAUSED,
        INGNAL,
    } FrameTrace;

    struct camera_frame_type queue_frame;
} DispatchFrameInfo_t;

2,Framelisten

Framelisten 里面有个枚举 policy_listen_type_t,共9个类型,就对对应9个framePolicy。我们后面会看到这个Framelisten经常出现的。
注意区分 listen_type_t 和 policy_listen_type_t

class Framelisten {
  public:
    typedef enum { LISTEN_LWP, LISTEN_HAL, LISTEN_REPROCESS, LISTEN_BPC, LISTEN_YUV, LISTEN_MAX } listen_type_t;

    typedef enum {
        POLICY_LISTEN_MIN = 0,
        POLICY_LISTEN_NORMALSINGLE_STREAMING = 1 << 0,//1
        POLICY_LISTEN_NORMALSINGLE_CAPTURE = 1 << 1,//2
        POLICY_LISTEN_MULTIFRAME_CAPTURE = 1 << 2,//4
        POLICY_LISTEN_RAWFRAME_CAPTURE = 1 << 3,//8
        POLICY_LISTEN_NOZSL_CAPTURE = 1 << 4,//16
        POLICY_LISTEN_FRAME_BUF_SWAP = 1 << 5,//32
        POLICY_LISTEN_RAWFRAME_SINGLE_CAPTURE = 1 << 6,//64
        POLICY_LISTEN_CAPTURE_BASE = 1 << 7,//128
        POLICY_LISTEN_CAPTURE_PTC = 1 << 8,//256
        POLICY_LISTEN_MAX = 1<<30,
    } policy_listen_type_t;

    Framelisten(policy_listen_type_t id) : policyTypeId(id){};
    virtual ~Framelisten() = default;
    /**
     * Listen for frames being processed
     */
    virtual void setCameraIf(SprdCamera3OEMIf *oem){};
    virtual int32_t onFrameAvailable(std::shared_ptr<DispatchFrameInfo_t> frame) = 0;
    policy_listen_type_t policyTypeId;
    vector<camera_frame_type> inputdataVec;
  };

3,FrameProducer

FrameDispatch中就定了3个函数,它的实现类是FrameProcesser.cpp

virtual int32_t waitForNextFrame(nsecs_t timeout) { return 0; };
virtual int32_t popOneBuffer(std::shared_ptr<DispatchFrameInfo_t>) { return 0; };
virtual CameraFrameDispatch::Framelisten::policy_listen_type_t getListenTypeByResult(std::shared_ptr<DispatchFrameInfo_t> frame) = 0;

4,RangeListener

RangeListener就像一个demo类,主要就是这连个数据成员组装到一起

struct RangeListener {
    CameraFrameDispatch::Framelisten::policy_listen_type_t typeId;
    weak_ptr<Framelisten> listener;
  };

关键数据成员和函数:

weak_ptr<FrameProducer> mProducer;
List<RangeListener> mRangeListeners;

int32_t registerListener(CameraFrameDispatch::Framelisten::policy_listen_type_t typeId,const std::shared_ptr<Framelisten> &listener);
int32_t removeListener(CameraFrameDispatch::Framelisten::policy_listen_type_t typeId,std::shared_ptr<Framelisten> &listener);

virtual bool threadLoop();
void processFrames(std::shared_ptr<FrameProducer> &producer);
int32_t processListeners(std::shared_ptr<DispatchFrameInfo_t> frame,const std::shared_ptr<FrameProducer> &producer);

再来看FrameDispatch.cpp文件实现

FrameDispatch.cpp:

1,registerListener 与 removeListener

就是维护了 List mRangeListeners; 数据成员

int32_t CameraFrameDispatch::registerListener(
    Framelisten::policy_listen_type_t typeId, const std::shared_ptr<Framelisten> &listener) {
    // Mutex::Autolock l(mInputMutex);
    List<RangeListener>::iterator item = mRangeListeners.begin();
    while (item != mRangeListeners.end()) {
        if (item->typeId == typeId && item->listener.lock() == listener) {
            LOGD("Attempt to register the same client twice, ignoring, typeId %d", typeId);
            return LWP_SUCCESS;
        }
        item++;
    }
    RangeListener rListener = {typeId, listener};
    mRangeListeners.push_back(rListener);
    LOGI("policy::%d, mRangeListeners size %d", typeId, mRangeListeners.size());
    return LWP_SUCCESS;
}

int32_t CameraFrameDispatch::removeListener(Framelisten::policy_listen_type_t typeId,
                                    std::shared_ptr<Framelisten> &listener) {
   Mutex::Autolock l(mInputMutex);
   List<RangeListener>::iterator item = mRangeListeners.begin();
    while (item != mRangeListeners.end()) {
        if (item->typeId == typeId && item->listener.lock() == listener) {
            item = mRangeListeners.erase(item);
        } else {
            item++;
        }
    }
    LOGI("policy %d, mRangeListeners size %d", typeId, mRangeListeners.size());
    return LWP_SUCCESS;
}

2,threadLoop

threadLoop 的流程绘制了如下流程图:ThreadLoop最终是要调用Framelisten的 onFrameAvailable
在这里插入图片描述

FrameProcesser

FrameProcesser.h

class cameraFrameProducer : public CameraFrameDispatch::FrameProducer

这个就是实现了我们上面说的CameraDispatch.h中定义的FrameProducer。不知道为什么要这样取名字,类名叫Producer,文件名却叫Processer。
.h 文件就是声明数据成员和函数成员,没有结构体和内部类

关键数据成员:

  map<result_list_type, list<struct camera_frame_type *>> mFrameDataMap;
  vector<shared_ptr<CameraFrameDispatch::Framelisten>> mListen;
  vector<stream_t> __stream_list;

关键函数成员:

ps系列:
void setPsOps(lwp_ops_t *ops);
void setPsHandle(cmr_u32 camera_id, void *oem_handle, void *prev_handle,
                   void *snp_handle, void *sns_handle, void *setting_handle,
                   void *grab_handle, void *isp_handle);
void clearPsHandle(cmr_u32 camera_id);

buffer系列:
virtual int32_t waitForNextFrame(nsecs_t timeout);
virtual int32_t popOneBuffer(std::shared_ptr<DispatchFrameInfo_t> frame);
virtual void pushBufferQueue(struct camera_frame_type *frame);
void requestBuffer(struct camera_frame_type *tmp_data) { return; }
int restoreBuffer(struct camera_frame_type *tmp_data) { return 0; }

stream系列:
void clearStream();
void addStream(stream_t stream, int32_t is_first_configure = 0);

生命周期相关系列:
bool producerInit(int32_t lwp_session);
bool producerStart(dispatch_cb cb = nullptr);
bool producerStop(dispatch_cb cb = nullptr);

other:
virtual policy_listen_type_t getListenTypeByResult(std::shared_ptr<DispatchFrameInfo_t> frame);

FrameProcesser.cpp

1,构造函数

  • clearResources
  • 清 AdapterRef
  • CtreatePolicyMgrInstance
cameraFrameProducer::cameraFrameProducer(SprdCamera3OEMIf *parent)
    : mPolicyMgr(nullptr), mOEMIf(parent), status(STATE_MIN) {
  clearResources();
  auto it = find_if(
        AdapterRef.begin(), AdapterRef.end(),
        [&](uint32_t adap) {
          return parent->mCameraId == adap;
        });
    if (it != AdapterRef.end()) {
        AdapterRef.erase(it);
    };

  std::unique_lock<std::mutex> l(mProducerLock);
  mPolicyMgr = FramePolicyMgr::CtreatePolicyMgrInstance();
  LOGD("Initialize cameraFrameProducer, mPolicyMgr %p", mPolicyMgr);
}

2,析构函数

  • clearResources
  • 清 AdapterRef
  • sessionAdapter的stop & delete & MsgBus
  • DestoryPolicyMgrInstance
cameraFrameProducer::~cameraFrameProducer() {
  clearResources();
  std::unique_lock<std::mutex> l(mProducerLock);
  {
    std::unique_lock<std::mutex> l(mAdapterRefLock);
    auto it = find_if(
          AdapterRef.begin(), AdapterRef.end(),
          [&](uint32_t adap) {
            return mOEMIf->mCameraId == adap;
          });

    if (it != AdapterRef.end()) {
      AdapterRef.erase(it);
     // AdapterRef.push_back(parent->mCameraId);
    };

    if (!AdapterRef.size() && sessionAdapter) {
      sessionAdapter->stop(nullptr);
      delete sessionAdapter;
      sessionAdapter = nullptr;
      gLwpMsgBus.removeAllListeners();
    }
  }

  if (mPolicyMgr) mPolicyMgr->DestoryPolicyMgrInstance();
  mPolicyMgr = nullptr;
  LOGD("Destory cameraFrameProducer, mPolicyMgr Object");
};

3,clearResource

清两个关键成员:mFrameDataMap 和 mListen

bool cameraFrameProducer::clearResources() {
  std::unique_lock<std::mutex> l(mProducerLock);

  for(auto & frameData:mFrameDataMap) {
    list<camera_frame_type *>::iterator item = frameData.second.begin();
    while (item != frameData.second.end()) {
      free(*item);
      item = frameData.second.erase(item);
    }
  }

  for(auto &l:mListen) {
      l->inputdataVec.clear();
  }
  return true;
}

4,ps系列

都是转到 sessionAdapter 中

void cameraFrameProducer::setPsOps(lwp_ops_t *ops) {
  if (sessionAdapter) {
    sessionAdapter->setPsOps(ops);
  } else {
    LOGE("sessionAdapter is NULL");
  }
}

void cameraFrameProducer::setPsHandle(cmr_u32 camera_id, void *oem_handle,
                                      void *prev_handle, void *snp_handle,
                                      void *sns_handle, void *setting_handle,
                                      void *grab_handle, void *isp_handle) {
  if (sessionAdapter) {
    mOEM = (struct camera_context *)oem_handle;
    sessionAdapter->setPsHandle(camera_id, oem_handle, prev_handle, snp_handle,
                                sns_handle, setting_handle, grab_handle,
                                isp_handle);
  } else {
    LOGE("sessionAdapter is NULL");
  }
}

5,stream系列

维护 __stream_list 集合

void cameraFrameProducer::clearStream() {
  LOGI("clear all stream");
  for (auto it = __stream_list.begin(); it != __stream_list.end();) {
      it = __stream_list.erase(it);
  }
}

void cameraFrameProducer::addStream(stream_t stream, int32_t is_first_configure) {
  auto it = find_if(
      __stream_list.begin(), __stream_list.end(), [&](const stream_t &sl) {
        return (sl.width == stream.width) && (sl.height == stream.height) &&
               (sl.format == stream.format);
      });
  if (it == __stream_list.end())
    __stream_list.push_back(stream);
  LOGI("stream_fmt %d, stream_size %dx%d, stream_list %d",
            stream.format, stream.width,
            stream.height, __stream_list.size());
}

6,生命周期系列:producerInit、producerStart、producerStop

sessionAdapter 是Lwp模块的内容,我们后续文章会讲解
在这里插入图片描述
producerStart 关键逻辑
在这里插入图片描述
producerStop 的关键代码:
在这里插入图片描述

7,pushBufferQueue 和 popOneBuffer

主要就是维护了 map<result_list_type, list<struct camera_frame_type *>> mFrameDataMap;

8,委托给PolicyMgr处理的函数

在这里插入图片描述
总结下:cameraFrameProducer 主要是作为一个中间过程,将参数数据转给 sessionAdapter 和 PolicyMgr。需要注意其与生命周期相关的三个函数,这三个函数的调用与Camera的open和预览流程相关。

FramePolicyMgr

FramePolicyMgr.h

1,模板类:ThreadJobQueue

主要是维护了一个 std::queue<JobQue_T> mQueue; insert、pop等

template <typename JobQue_T> class ThreadJobQueue

2,结构体及指针函数

在这里插入图片描述

3,policyFrameThread

这个内部类的内容很短,是个Thread类型,关键点是在其loop中调用FramePolicy类型的 startThread
在这里插入图片描述

4,模板类 FramePolicy ,继承自FramePolicyBase

其中包含一个数据成员是 policyFrameThread

template <typename JobQue_T> class FramePolicy : public FramePolicyBase

关键成员:
ThreadJobQueue<JobQue_T> mThreadQueue;
sp<policyFrameThread> mListenThread;

mThreadQueue 就是一个queue,用来装数据的一个集合:

void enqueThreadJob(JobQue_T value) {
   return mThreadQueue.InsertQue(value);
};
bool clearThreadJob() { 
   return mThreadQueue.Clear(); 
};

bool dequeThreadJob(JobQue_T &value) { 
	return mThreadQueue.PopQue(value);
};

5,FramePolicyMgr的声明

关键数据成员

std::map<policy_listen_type_t, sp<FramePolicyBase>> mPolicyTabelMap;

std::map<uint32_t, uint32_t> snapReq_list;
std::map<uint32_t, std::shared_ptr<request_info_t>> mRequestInfo;

MsgNotifier<bufferFd, Buffer *> requestCompleted;

void *sHandler[20];

关键函数:

match系列:
policy_listen_type_t matchPolicy(std::shared_ptr<DispatchFrameInfo_t> frame);
policy_listen_type_t matchPolicy(dispatch_request_info &Req);      //*request info*/

构造与析构:
static FramePolicyMgr *CtreatePolicyMgrInstance();
void DestoryPolicyMgrInstance();

Buffer系列:
int32_t request(dispatch_request_info &Req);
void qRequestParams(request_info_t &param);
void dqRequestParams(uint32_t frame_num);
int32_t returnZslBuffer(int32_t frame_fd);
void clearBufferList();

回调:
int32_t onLwpDataArrivedListener(PipeLineType &type,Buffer *buffer, void *priv);

policyLoad:
int32_t policyModulesLoad();
void policyModulesLoadSelf();

好多函数在上一节介绍 cameraFrameProducer 的时候提到过,是从 cameraFrameProducer 调过来的。

FramePolicyMgr.cpp

1,内部类:class preLoaderPolicy

遍历:static const char *policy_modules_path = “/odm/lib/lwpPolicy”; 路径下的so文件
在这里插入图片描述
将读到的so中的handler转到 mHandler中
find lib path的log打印
在这里插入图片描述

2,FramePolicyMgr 的构造与析构

构造函数:
memset(sHandler, 0, sizeof(sHandler));

析构函数主要做一些资源的释放工作
在这里插入图片描述

3,match 系列

math就是遍历 mPolicyMap中所有policy的match。
request 和 returnZslBuffer 也是同样的道理
在这里插入图片描述

4,mRequestInfo 集合数据的维护

在这里插入图片描述

5,FramePolicyMgr::policyModulesLoadSelf

遍历所有Policy的so文件,和上面 class preLoaderPolicy 的流程是一样的

6,FramePolicyMgr::policyModulesLoad

先看下 preLoaderPolicy 有没有正常加载了Policy,没有的话,就调用自己的 policyModulesLoadSelf 加载。

7,FramePolicyMgr::policyModulesLoad

实例化so库的各个policy,并将其装入到 mPolicyTabelMap 中
在这里插入图片描述
总结下 FramePolicyMgr.cpp,主要是加载9个so库中的policy,将其装入到 std::map<policy_listen_type_t, sp> mPolicyTabelMap;
然后在各个函数调用中把请求转到对应的policy中去处理。

本篇文章主要介绍三个cpp文件:FrameDispatch.cpp、FrameProcesser.cpp、FramePolicyMgr.cpp。作为dispatch模块的入口,在接收到数据和请求后,主要是进一步向下调用。让我们期待后面的流程介绍吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931106.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

移动,电信,联通流量卡该怎么选?

是电信便宜&#xff0c;移动稳定&#xff0c;还是联通性价比高&#xff1f; ​ 今天&#xff0c;小编从三大流量卡的优缺点方面来讲&#xff0c;教你如何选择流量卡了。 一、移动流量卡 优点&#xff1a;信号好&#xff0c;可以说走到什么地方都有信号。 缺点&#xff1a;资…

Leaflet开发入门

Leaflet开发入门 开发环境配置Leaflet开发库开发移动端Hybrid App或移动Web App 开发环境配置 电子地图已经渗透到O2O、生活服务、出行等领域&#xff0c;传统的GIS也孕育着互联网基因。在国内互联网电子地图领域&#xff0c;百度地图和高德地图较为出色&#xff0c;天地图作为…

js的使用之时间如何定义,窗口加载事件

1.时间如何定义 1.1 date的其他的属性 带出星期几的写法 var arr [星期日,星期一,星期二,星期三,星期四,星期五,星期六,星期天] var day date.getDay(); console.log(arr[day]); 1.2 日期的格式化 1.3 时分秒的写法 固定写法&#xff1a;如果想要写成00:00:00这种形式&am…

阿里云服务器搭建FRP实现内网穿透-P2P

前言 在了解frp - p2p之前&#xff0c;请先了解阿里云服务器搭建FRP实现内网穿透-转发: 文章地址 1、什么是frp - p2p frp&#xff08;Fast Reverse Proxy&#xff09;是一个开源的反向代理工具&#xff0c;它提供了多种功能&#xff0c;包括端口映射、流量转发和内网穿透等。…

cmake 交叉编译应用程序:手动设置链接脚本

前言 在使用 cmake 交叉编译应该应用程序时&#xff0c;好像没有手动设置【链接脚本】&#xff0c;也能正常构建生成 Makefile&#xff0c;并且可以正常 Make 生成需要的 应用程序。 但是有些应用程序&#xff0c;需要手动指定【链接脚本】&#xff0c;比如修改链接地址&#…

五、多表查询-5.自连接

一、语法 二、演示-自连接&#xff08;内连接&#xff09; 【例】查询员工 及其 所属领导的名字&#xff08;managerid&#xff0c;领导也是员工表emp1表中的数据&#xff09; &#xff01;&#xff01;必须起别名&#xff01;&#xff01; ——内连接只查询交集部分的数据 …

微调真香,漫画科技博主竟然在用国产大模型生成系列漫画女主角

有一说一&#xff0c;《微调真香&#xff0c;漫画科技博主竟然在用国产大模型生成系列漫画女主角》不是标题党。 连我也不得不相信&#xff0c;作为“亲爱的数据”创始人&#xff0c;我确实在用人工智能大模型生成自家特有风格的漫画。 市面上&#xff0c;海内外&#xff0c;用…

HAproxy服务及keepalived+haproxy高可用

本节主要学习AHproxy 的概述&#xff0c;安装&#xff0c;调度算法&#xff0c;配置文件&#xff0c;负载均衡&#xff0c;配置syslog日志&#xff0c;keepalivedhaproxy实现高可用。 目录 一、概述 1、简介 2、核心功能 3、关键特性 4、应用场景 二、安装 1.内核配置 …

【附安装包】Marvelous designer12|3D服装设计

软件下载 软件&#xff1a;Marvelous designer版本&#xff1a;12语言&#xff1a;简体中文大小&#xff1a;1.49G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a;https://p…

X(推特)推出招聘平台,马斯克进军招聘领域,欲对标 LinkedIn

8 月 26 日&#xff0c;埃隆・马斯克接手 X&#xff08;推特&#xff09;后&#xff0c;开启了一系列备受争议的变革&#xff0c;并多次在公开场合表示希望将 X 打造成为超级应用&#xff0c;受人瞩目。除了私信中推出了视频聊天和语音聊天功能之外&#xff0c;X 在今天宣布上线…

无涯教程-机器学习 - 数据加载

假设如果要启动ML项目&#xff0c;那么您需要做的第一件事也是最重要的事情是什么?这是无涯教程启动任何ML项目都需要加载的数据。关于数据&#xff0c;对于ML项目&#xff0c;最常见的数据格式是CSV(逗号分隔值)。 基本上&#xff0c;CSV是一种简单的文件格式&#xff0c;用…

网络字节序——TCP接口及其实现简单TCP服务器

网络字节序——TCP接口及其实现简单TCP服务器 文章目录 网络字节序——TCP接口及其实现简单TCP服务器简单TCP服务器的实现1. 单进程版&#xff1a;客户端串行版2. 多进程版&#xff1a;客户端并行版netstat查看网络信息3.多线程版&#xff1a;并行执行log.hpp 守护进程fg、bg s…

BI技巧丨Window应用之同环比

白茶曾介绍过OFFSET可以用来解决同环比的问题&#xff0c;其实微软最近推出的开窗函数WINDOW也可以用来解决同环比。 WINDOW函数基础语法 WINDOW ( from[, from_type], to[, to_type][, <relation>][, <orderBy>][, <blanks>][, <partitionBy>][, &l…

[论文分享]Skip-Attention: Improving Vision Transformers by Paying Less Attention

Skip-Attention: Improving Vision Transformers by Paying Less Attention 这项工作旨在提高视觉transformer&#xff08;ViT&#xff09;的效率。 虽然 ViT 在每一层都使用计算昂贵的自我注意操作&#xff0c;但我们发现这些操作在各层之间高度相关——这是导致不必要的计算的…

计算机网络-笔记-第二章-计算机网络概述

目录 二、第二章——物理层 1、物理层的基本概念 2、物理层下面的传输媒体 &#xff08;1&#xff09;光纤、同轴电缆、双绞线、电力线【导引型】 &#xff08;2&#xff09;无线电波、微波、红外线、可见光【非导引型】 &#xff08;3&#xff09;无线电【频谱的使用】 …

linux问题定位

1.CPU工作原理 2.Linux内存分配 3.栈 1&#xff09;.存储局部变量 函数参数 函数返回值的地方 2&#xff09;.每个线程的栈空间连续且相互独立 3&#xff09;.使用 x /100a $esp 可以看到栈内存中的原始数据 3.函数调用过程 函数调用过程在栈中如何组织数据的 4.堆 三级堆管理…

研磨设计模式day13组合模式

目录 场景 不用模式实现 代码实现 有何问题 解决方案 代码改造 组合模式优缺点 思考 何时选用 场景 不用模式实现 代码实现 叶子对象 package day14组合模式;/*** 叶子对象*/ public class Leaf {/*** 叶子对象的名字*/private String name "";/**…

KVM虚拟化平台安装及创建虚拟机

文章目录 一、KVM 简介二、安装KVM虚拟化平台1、方式一&#xff1a;安装操作系统时&#xff0c;添加虚拟化功能2、方式二&#xff1a;基于现有系统&#xff0c;安装虚拟化功能3、验证KVM安装是否无误 三、创建虚拟机1、创建虚拟机前环境准备工作2、创建CentOS7.5系统虚拟机 一、…

网工必备知识之——防火墙篇

目录 一、背景 二、类型 2.1.过滤防火墙 2.2.应用网关防火墙 2.3.服务防火墙 2.4.监控防火墙 三、功能 3.1.网络安全屏障 3.2.网络安全策略 3.3.进行监控审计 3.4.防止内部信息的外泄 四、五个安全域 五、三种工作模式 5.1交换模式(二层模式): 5.2路由模式(三层…

恶意软件分析和取证:深入研究各类恶意软件,讨论分析技术和数字取证方法,了解攻击者的行为和动机

章节一&#xff1a;引言 在当今数字化的世界中&#xff0c;恶意软件的威胁不断演化&#xff0c;给个人、企业 ja 尤其是政府带来了巨大的安全风险。恶意软件如病毒、木马、蠕虫等形式多样&#xff0c;攻击手段不断升级&#xff0c;导致了信息泄露、财产损失 ja 甚至国家安全的…