赞
踩
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
参考:https://man7.org/linux/man-pages/man2/mmap.2.html
参考:https://blog.csdn.net/chdhust/article/details/8159397
参考:https://www.cnblogs.com/52php/p/5861372.html
参考:https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-createfilemappinga
作为本地进程间通信中非常高效的手段,共享内存是一个优点很明显,缺点也很明显的进程间数据传递的方式。
核心优点:是通过地址映射直接共享访问内存,适合于大数据量的进程间传送。
主要缺点:是没有进程间访问同步的约束,不解决进程间访问冲突,需要额外的同步机制来保证。
共享内存ShareMemory优点:
共享内存ShareMemory缺点:
windows与linux都提供了共享内存相关服务,大概可以分为三种
第一种,是内存映射文件,既有共享内存,又会向文件同步;
第二种,采用内存映射文件方式,不提供文件,
第三种,命名共享内存,
通过mmap函数,提供两种内存映射方式:
a. mmap-fd有效情况,对文件的内容映射到共享内存,多进程间可以通过该共享内存互访对数据的修改和使用。
b. mmap-fd=-1的情况,创建匿名访问共享内存MAP_ANONYMOUS,不涉及文件打开与关闭,用于亲缘关系的父子进程间;
(注意,mmap之后,文件fd就可以关闭了.)
mmap/munmap函数定义
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags,
int fd, off_t offset);
int munmap(void *addr, size_t length);
通过shmget函数,提供一种方式:
a. 创建类似实名的共享内存,共享内存对应key,通过key能找到共享内存
#include <sys/ipc.h>
#include <sys/shm.h>
key_t key = ftok("/tmp", 0x3f);
int shmid = shmget(key, 1024, 0666|IPC_CREAT); // create if not exist share memory for key
char *shm = (char*)shmat(shmid, 0, 0); // map mem to the process
...
shmdt(shm); // unmap mem from the process
shmctl(shmid, IPC_RMID, 0); // remove share memory for key
通过函数CreateFileMapping提供共享内存创建的几种方式:
a. hFile有效情况,对文件内容映射到共享内存中,可以基于hFile进行进程间共享;也可以指定share memory name进行进程间共享;
b. hFile为-1|INVALID_HANDLE_VALUE时,指定SizeHigh/SizeLow来确定共享内存的大小,并指定SecurityAttr属性,来创建共享内存。
c. hFile为-1|INVALID_HANDLE_VALUE时,还可以通过指定share memory name,基于该名称进行进程间共享;
用到的函数定义
// 获取共享内存handle
HANDLE CreateFileMappingA(
[in] HANDLE hFile,
[in, optional] LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
[in] DWORD flProtect,
[in] DWORD dwMaximumSizeHigh,
[in] DWORD dwMaximumSizeLow,
[in, optional] LPCSTR lpName
);
// 映射到进程内存
LPVOID MapViewOfFile(
[in] HANDLE hFileMappingObject,
[in] DWORD dwDesiredAccess,
[in] DWORD dwFileOffsetHigh,
[in] DWORD dwFileOffsetLow,
[in] SIZE_T dwNumberOfBytesToMap
);
linux下三种方式来说,
mmap与shmget方式的话,可以用于
a. 通过文件映射的内存共享
b. 父子进程基于纯内存的内存共享
c. 基于key对应纯内存的内存共享
windows下:createFileMapping可以用于
a. 通过文件映射的内存共享
b. 父子进程-基于匿名对应纯内存的内存共享
c. 基于名称对应纯内存的内存共享
对于通过文件映射的内存共享,两者实现的支持是一致的,实现上
linux使用mmap-有效fd
window使用createrFileMapping-有效filehandle
对于父子进程基于纯内存的内存共享,两者也分别可以实现匿名共享
liunx使用mmap-fd使用-1,参数使用MAP_ANONYMOUS
window使用createrFileMapping-file使用INVALID_HANDLE_VALUE,不指定share memory name;
对于进程基于id或名称对应关系,基于纯内存的内存共享:
linux使用shmget,使用key对应共享内存
windows使用createrFileMapping-file使用INVALID_HANDLE_VALUE,指定share memroy name,基于名称对应共享内存
共享内存同步的话,一般就要采用其它进程间同步机制来保证了:
windows下提供的有:
a. 命名锁,命名信号量,命名Event,这些都可以提供进程间的通信;
b. 另外还有命名管道,windows的消息机制也都可以提供进行间通信;
c. 当然socket通信也是可以的。
linux下提供的有:
a. Systemv-信号量,Systemv-消息msg
b. posix-信号量,posix-消息msg
c. 也有命名锁
d. 当然也有socket通信
e. 另外在共享内存中创建pthread-mutex,用于进程间加锁互斥也是可以的,不过锁创建时一般也还要借助于其它同步机制确保创建不可重入;
其它同步方法应该还有,欢迎补充。
(Owed by: 春夜喜雨 http://blog.csdn.net/chunyexiyu)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。