1.进程逻辑空间和物理空间
如上图所示,每个进程都有自己的逻辑空间,这些逻辑空间被映射到具体的物理空间。
各个进程的逻辑空间是相互分离、相互独立、不间断的。
然而,它们都映射到同一个物理空间,如果映射的物理空间重叠,则重叠部分共享物理内存。
2. 共享内存的主要问题
创建物理内存
将物理内存映射到进程空间
读写控制互斥
1)创建物理内存并获取物理内存资源句柄。
例如,进程A负责创建共享内存。
A: 进程创建物理内存后,直接返回物理内存句柄。
//创建共享文件句柄HANDLE hMapFile=CreateFileMapping( INVALID_HANDLE_VALUE, //物理文件句柄NULL, //默认安全级别PAGE_READWRITE, //可读可写0, //高文件大小BUF_SIZE, //低文件大小L \\\’ ShareMemory \\\’ //共享内存名称);B:进程B通过共享内存全局名称获取共享物理内存句柄
//打开共享文件对象HANDLE hMapFile=OpenFileMapping(FILE_MAP_ALL_ACCESS,NULL,L\\\’ShareMemory\\\’);2) 物理内存映射进程空间
这样,每个进程就将物理空间中的共享内存映射到进程的逻辑空间中。
//映射缓存视图并获取指向共享内存的指针。 LPVOID lpBase=MapViewOfFile( hMapFile, //共享内存句柄FILE_MAP_ALL_ACCESS, //读写权限0, 0, BUF_SIZE );3) free
进程完成后取消映射
//取消文件映射
UnmapViewOfFile(lpBase);
//关闭内存映射文件对象句柄
关闭句柄(hMapFile);
4)互斥控制
使用互斥体或信号机制
互斥机制
进程A: 创建互斥体while(1) { 释放互斥体; 进程B: { 释放互斥体} 示例:
工艺A
#include #include using namespace std; int main(){//如果不存在,则创建名为“pmutex”的互斥体,否则获取其句柄。 HANDLE hMutex=CreateMutex(NULL, false, \\\’pmutex\\ \’) ); if(NULL==hMutex) { cout\\\’互斥体创建错误\\\’进程B
#include #include using namespace std; int main(){//如果不存在,则创建名为“pmutex”的互斥体,否则获取其句柄。 HANDLE hMutex=CreateMutex(NULL, false, \\\’pmutex\\ \’) ); if(NULL==hMutex) { cout\\\’创建互斥体时出错\\\’信号量机制:
进程A:执行写操作
进程A执行写操作//等待其他进程完成读操作WaitForSingleObject(m_memMng.m_hReadEvent, INFINITE) //重置写操作信号量ResetEvent(m_memMng.m_hWriteEvent) //Write 执行操作memcpy //写完后恢复操作完成,使信号量可由其他进程读取。 SetEvent(m_memMng.m_hWriteEvent); 进程B:执行读操作。
//进程B执行读操作。 //等待主进程写完。 WaitForSingleObject(m_memMng.m_hWriteEvent, INFINITE) //重置读取信号量。 ResetEvent(m_memMng.m_hReadEvent); //读操作,复制共享内存数据。局部变量memcpy中//一旦读操作完成,将信号量信号SetEvent(m_memMng.m_hReadEvent)设置为三个包。
必须存在的成员变量:
1)创建物理内存并映射进程空间管理
处理hMapping_;
MappedView View_; 操纵物理映射到进程空间
int 大小_;
std:wstring name_; 共享内存名称
2)信号量控制管理
处理m_hReadEvent。
处理m_hWriteEvent。
操作方法:
1)创建
bool CreateFileMap(); //创建
bool OpenFileMap(); //如果已经存在则打开。
bool MapView(bool bCanWrite=true); //映射进程空间。
2)映射管理类
class MappedView{public:MappedView() : view_(NULL) {}~MappedView() { CloseView(); }bool MapView(SharedMemory *shared_memory, bool can_write);//MapViewOfFilevoid CloseView();char *view() { return view_; } }private: char *view_=nullptr;};共享内存管理类
类SharedMemory{public:SharedMemory() : hMapping_(NULL) {size_=0;m_hReadEvent=NULL;m_hWriteEvent=NULL;}~SharedMemory() { Close(); if (m_hReadEvent) {CloseHandle(m_hReadEvent) }if (m_hWriteEvent)CloseHandle ( m_hWriteEvent);};public://InitReceiver 初始化(std:wstring name, std:wstring readName=L\\\’ShareMemoryReadEvent\\\’, std:wstring writeName=L\\\’ShareMemoryWriteEvent\\\’);//初始化接收器bool Init Create (std :w字符列名,int size, std:wstring readName=L\\\’ShareMemoryReadEvent\\\’, std:wstring writeName=L\\\’ShareMemoryWriteEvent\\\’); //初始化创建者private:bool CreateFileMap();bool OpenFileMap();bool MapView(bool bCanWrite=true);void Close() ; public:char* getData();int getSize(){return size_;}public://信号量管理void WaitForSingleObject_Read();void WaitForSingleObject_Write();void ResetEventNull_Read();void ResetEventNull_Write();void SetEvent_Read ();void SetEvent_Write( ) ; private:friend class MappedView;MappedView View_;HANDLE hMapping_=nullptr;int size_=0;std:wstring name_;public:HANDLE m_hReadEvent=nullptr;HANDLE m_hWriteEvent=nullptr;std:wstring m_ReadEvent tName; //跨进程信号量L \”Global “ std:wstring m_WriteEventName;};应用示例:
主进程发送摄像头数据
主进程SharedMemory m_memMng;m_memMng.InitCreate(L\\\’sharedCamera\\\’, 1920 * 1080 * 3/2 + 12);//0|1 状态+ 宽度+ 高度///////////////////////////////////////////////////////////////////char* pData=m_memMng.getData();INT32 nFps=g_pLiveForm-m_videoFps;INT32 nWidth=宽度;INT32 nHeight=高度;INT32 Info[]={ nFps, nWidth, nHeight };int len=sizeof( Info )/sizeof (Info[0]);if (pData){m_memMng.WaitForSingleObject_Read();m_memMng.ResetEventNull_Write();memcpy((INT32*)pData, Info, sizeof(INT32)*len);memcpy( pData + 12、nim_nls:LssManange: GetVideoFrameMng()-capture_video_pic_.pdata_, nim_nls:LssManange:GetVideoFrameMng()-capture_video_pic_.size_);m_memMng.SetEvent_W rite () ;} 子进程读取相机数据
sharedMemory m_memmng; m_memmng.initreceiver(l \\\’sharedCamera \\\’); //阅读m_memmng.waitforsingleobject_write() m_memmng.m_hread事件) );char* pData=m_memMng.getData();if (pData){INT32 nFps=20;INT32 nWidth=width_;INT32 nHeight=height_;INT32 Info[]={ 0, nWidth, nHeight };int len=sizeof ( 信息)/sizeof(信息[0]);memcpy(信息, (INT32*)pData, sizeof(INT32)*len);nFps=信息[0];nwidth=信息[1];nheight=信息[ 2 ]; memcpy ((char*)data_temp.c_str(), pData + 12, nWidth*nHeight * 3/2);m_memMng.SetEvent_Read(); //SetEvent(m_memMng.m_hReadEvent);
本文和图片来自网络,不代表火豚游戏立场,如若侵权请联系我们删除:https://www.huotun.com/game/667868.html