当前位置:   article > 正文

进程间通信IPC-共享内存ShareMemory_qsharememory creat

qsharememory creat

(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优点:

  1. 数据不需要进程间传送,直接通过地址映射访问share memory即可,适合于大数据量的进程间传递。
  2. 访问的各方不需要建立链接关系,例如使用管道时需要建立进程间管道的连接关系,使用socket-tcp通信时同样要建立tcp链接;
  3. 不涉及访问个数限制;
  4. 缺省情况下,访问方均可以读写;

共享内存ShareMemory缺点:

  1. 共享内存没有提供同步的机制,使用时,需要借助其它方法同步进程间的share memory访问;

共享内存实现

windows与linux都提供了共享内存相关服务,大概可以分为三种
第一种,是内存映射文件,既有共享内存,又会向文件同步;
第二种,采用内存映射文件方式,不提供文件,
第三种,命名共享内存,

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);
  • 1
  • 2
  • 3
  • 4

通过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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
windows下

通过函数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
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
linux与windows实现对应

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)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/1000842
推荐阅读
相关标签
  

闽ICP备14008679号