细说linux IPC(四):posix 共享内存

上一节讲了由open函数打开一个内存映射文件,再由mmap函数把得到的描述符映射到当前进程地址空间中来。这一节说说另外一种类似的共享内存方法,即 有shm_open函数打开一个Posix.1 IPC名字(也许是文件系统中的一个路径名),所返回的描述符由函数mmap映射到当前进程地址空间。
        
posix共享内存和尚上一节类似,首先需要制定一个名字参数调用shm_open ,以创建一个新的共享内存对象或打开一个已存在的共享内存对象;然后再调用mmap把共享内存区映射到调用进程的地址空间中。
shm_open函数原型如下:

  1. #include <sys/mman.h>
  2. #include <sys/stat.h> /* For mode constants */
  3. #include <fcntl.h> /* For O_* constants */
  4. int shm_open(const char *name, int oflag, mode_t mode);
  5. Link with -lrt.

参数name为将要被打开或创建的共享内存对象,需要指定为/name的格式。
参数oflag必须要有O_RDONLY(只读)、标志O_RDWR(读写),除此之外还可以指定O_CREAT(没有共享对象则创建)、O_EXCL(如果O_CREAT指定,但name不存在,就返回错误)、O_TRUNC(如果共享内存存在,长度就截断为0)。
参数mode为指定权限位,在指定了O_CREAT的前提下使用,如果没有指定O_CREAT,mode可以指定为0.

该函数返回一个描述符,在mmap函数(见上一节)第五个参数使用。

  1. #define SHM_IPC_FILENAME "sln_shm_file"
  2. #define SHM_IPC_MAX_LEN 1024

ser:

  1. int sln_shm_get(char *shm_file, void **shm, int mem_len)
  2. {
  3. int fd;
  4. fd = shm_open(shm_file, O_RDWR | O_CREAT, 0644);
  5. if (fd < 0) {
  6. printf("shm_open <%s> failed: %s\n", shm_file, strerror(errno));
  7. return -1;
  8. }
  9. ftruncate(fd, mem_len);
  10. *shm = mmap(NULL, mem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  11. if (MAP_FAILED == *shm) {
  12. printf("mmap: %s\n", strerror(errno));
  13. return -1;
  14. }
  15. close(fd);
  16. return 0;
  17. }
  18. int main(int argc, const char *argv[])
  19. {
  20. char *shm_buf = NULL;
  21. sln_shm_get(SHM_IPC_FILENAME, (void **)&shm_buf, SHM_IPC_MAX_LEN);
  22. snprintf(shm_buf, SHM_IPC_MAX_LEN, "ipc client get: hello posix share memory ipc! This is write by server.");
  23. return 0;
  24. }

编译执行结果如下:

  1. # ./server
  2. # ./client
  3. ipc client get: hello posix share memory ipc! This is write by server.
  4. #

shm_open创建的文件位置位于 /dev/shm/ 目录下:

  1. # ll /dev/shm/
  2. -rw-r--r-- 1 root root 8193 Oct 30 14:13 sln_shm_file
  3. #

posix共享内存同步可以使用posix信号量来实现,具体在后面同步相关专栏会有详细讲解。
本节源码下载:
http://download.csdn.net/detail/gentleliu/8140869

时间: 2024-12-16 16:37:38

细说linux IPC(四):posix 共享内存的相关文章

linux进程间通信之Posix共享内存用法详解及代码举例

Posix共享内存有两种非亲缘进程间的共享内存方法:1).  使用内存映射文件,由open函数打开,再由mmap函数把返回的文件描述符映射到当前进程空间中的一个文件. 2). 使用共享内存区对象,由shm_open打开一个 Posix IPC名字.再由mmap把返回的描述符映射到当前进程的地址空间. Posix共享内存相关函数头文件及原型:#include <sys/mman.h>int shm_open(const char *name, int oflag, mode_t mode);功能

Linux IPC实践(8) --共享内存/内存映射

概述 共享内存区是最快的IPC形式.一旦这样的内存映射到共享它的进程的地址空间,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据(如图). 共享内存 VS. 其他IPC形式 用管道/消息队列传递数据 用共享内存传递数据 共享内存生成之后,传递数据并不需要再走Linux内核,共享内存允许两个或多个进程共享一个给定的存储区域,数据并不需要在多个进程之间进行复制,因此,共享内存的传输速度更快! mmap内存映射 将文件/设备空间映射到共享内存区 #incl

细说linux IPC(三):mmap系统调用共享内存

前面讲到socket的进程间通信方式,这种方式在进程间传递数据时首先需要从进程1地址空间中把数据拷贝到内核,内核再将数据拷贝到进程2的地址空间 中,也就是数据传递需要经过内核传递.这样在处理较多数据时效率不是很高,而让多个进程共享一片内存区则解决了之前socket进程通信的问题.共享内存 是最快的进程间通信 ,将一片内存映射到多个进程地址空间中,那么进程间的数据传递将不在涉及内核.        共享内存并不是从某一进程拥有的内存中划分出来的:进程的内存总是私有的.共享内存是从系统的空闲内存池中

细说linux IPC(五):system V共享内存

system V共享内存和posix共享内存类似,system V共享内存是调用shmget函数和shamat函数.           shmget函数创建共享内存区,或者访问一个存在的内存区,类似系统调用共享内存的open和posix共享内存shm_open函数.shmget函数原型为: #include <sys/ipc.h> #include <sys/shm.h> int shmget(key_t key, size_t size, int shmflg); key: 函

Linux IPC实践(10) --Posix共享内存

1. 创建/获取一个共享内存 #include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ int shm_open(const char *name, int oflag, mode_t mode); 参数: name:  共享内存名字; oflag: 与open函数类型, 可以是O_RDONLY, O_WR

linux c编程:Posix共享内存区

Posix共享内存区:共享内存是最快的可用IPC形式.它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存.如果需要在两个进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存区映射到共享它的进程的地址空间,这些进程间数据的传输就不再涉及内核.这样就可以减少系统调用时间,提高程序效率.共享内存是由IPC为一个进程创建的一个特殊的地址范围,它将出现在进程的地址空间中.其他进程可以把同一段共享内存段“连接到”它们自己的地址空间里去.所有进程都可以访问共享内存中的地址.如果一个进程

Linux环境编程之共享内存区(二):Posix共享内存区

现在将共享内存区的概念扩展到将无亲缘关系进程间共享的内存区包括在内.Posix提供了两种在无亲缘关系进程间共享内存区的方法: 1.内存映射文件:由open函数打开,由mmap函数把得到的描述符映射到当前进程地址空间中的一个文件.(上一节就是这种技术) 2.共享内存区对象:由shm_open打开一个Posix名字(也许是在文件系统中的一个路径名),所返回的描述符由mmap函数映射到当前进程的地址空间.(本节内容) Posix共享内存区涉及以下两个步骤要求: 1.指定一个名字参数调用shm_open

linux网络编程之posix共享内存

今天继续研究posix IPC对象,这次主要是学习一下posix共享内存的使用方法,下面开始: 下面编写程序来创建一个共享内存: 编译运行: 那posix的共享内存存放在哪里呢?上节中学的posix的消息队列是在虚拟文件当中创建一个消息队列,需要我们手工将它挂载到某个目录下才能看到,同样的,posix共享内存也是需要将其挂载,只不过这个挂载操作是由系统完成的,而不用我们人工去操作了,已经挂载到了/dev/shm下了,如下: 接下来要介绍的函数为修改共享内存的大小: [说明]:实际上ftrunca

细说linux IPC(十一):各种IPC形式比较总结(完)

[版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 这个系列基本上到现在为止已经差不多把linux上的各种常用的IPC介绍完了,linux上面的IPC大多都是从UNIX上面继承而来. 最初Unix IPC包括:管道.FIFO.信号.System V IPC包括:System V消息队列.System V信号灯.System V共享内存区.由于Unix版本的多样性,电子电气工程协会(IEEE)开发