一、共享内存定义二、Linux下使用
1.基本思路2.关键函数 三、Windows下使用
1.基本思路2.关键函数 四、共享内存优缺点
一、共享内存定义
共享内存是一种用于实现进程间通信(IPC)的方法,不同进程通过访问同一块内存区域实现数据共享和交互,是最快的可用IPC形式(其他进程间通信方式有:信号、管道、消息队列、网络套接字)。
每个进程可以将自身的虚拟地址映射到物理内存中的特定区域,当不同进程将相同的物理内存区域与各自的虚拟地址空间关联时,这些进程就能实现通过共享内存来完成IPC。若某进程更改了共享内存区的内容,其它进程都会觉察到该区域的更改。
每个进程有自己的进程控制块和地址空间,且都有一个与之对应的页表,负责将进程的虚拟地址与物理地址进行映射,通过内存管理单元(MMU)进行管理。两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。
二、Linux下使用 1.基本思路
Linux下共享内存可以通过tmpfs文件系统来实现,tmpfs默认的挂载目录为/dev/shm,它是基于RAM的文件系统,因此读写速度与读写内存速度一样,在不用的时候系统会自动删除掉。
首先利用shm_open()创建或者打开一个共享内存文件,然后ftruncate()将文件大小设置为共享内存大小,mmap()再将该文件映射到内存。
2.关键函数#include
int shm_open(const char* name, int oflag, mode_t mode);
参数说明:
O_CREAT:若此文件不存在则进行创建
O_RDWR:打开读写权限
O_EXCL : 如果同时指定了O_CREAT,而文件已经存在,则报错
注意:返回值表示文件描述字,如成功则大于0,失败则小于0
void *mmap(void *addr, size_t len, int prot, int flags,int fd, off_t offset);
参数说明:
PROT_EXEC:页内容可以被执
PROT_READ:页内容可以被读取
PROT_WRITE:页可以被写入
PROT_NONE:页不可访问
MAP_SHARED:与其它所有映射这个对象的进程共享映射空间,对共享区的写入,相当于输出到文件
MAP_PRIVATE:建立一个写入时拷贝的私有映射,内存区域的写入不会影响到原文件,这个标志和以上标志是互斥的,只能使用其中一个
MAP_ANONYMOUS:匿名映射,映射区不与任何文件关联
三、Windows下使用 1.基本思路
Windows下共享内存是通过FileMapping实现的。
首先CreateFileMapping()创建内存映射文件对象,即在物理内存申请一块指定大小的内存区域,返回文件映射对象的句柄。然后MapViewOfFile()能够访问内存区域,促使Windows将此内存空间映射到进程的地址空间中。当在其他进程访问这块内存区域时,OpenFileMapping()取得对象句柄,进行读写 *** 作。
2.关键函数#include
HANDLE WINAPI CreateFileMapping( _In_HANDLE hFile, _In_opt_LPSECURITY_ATTRIBUTES lpAttributes, _In_DWORD flProtect, _In_DWORD dwMaximumSizeHigh, _In_DWORD dwMaximumSizeLow, _In_opt_LPCTSTR lpName);
参数说明:
PAGE_READONLY:以只读方式打开映射
PAGE_READWRITE:以可读、可写方式打开映射
PAGE_WRITECOPY :为写 *** 作留下备份
注意:CreateFileMapping()可以用GetLastError()来检查其返回的错误信息。
LPVOID WINAPI MapViewOfFile( __in HANDLE hFileMappingObject, __in DWORD dwDesiredAccess, __in DWORD dwFileOffsetHigh, __in DWORD dwFileOffsetLow, __in SIZE_T dwNumberOfBytesToMap );
参数说明:
FILE_MAP_ALL_ACCESS:文件映射对象被创建时必须指定PAGE_READWRITE 选项.
FILE_MAP_COPY:可以读取和写入文件,写入 *** 作会导致系统为该页面创建一份副本
FILE_MAP_EXECUTE:可以将文件中的数据作为代码来执行
FILE_MAP_READ :可以读取文件
FILE_MAP_WRITE:可以读取和写入文件
四、共享内存优缺点
优点:进程间通信效率高,通过直接访问内存,是最快的IPC可用形式。不同于其他进程间通信方式,只需拷贝两次数据(输入数据->共享内存区->输出数据)。缺点:没有提供进程同步机制,需借助其他手段(如信号量),解决进程间协作关系。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)