Linux下基于POSIX标准的共享内存操作示例
来源:互联网 发布:淘宝助理不能上传 编辑:程序博客网 时间:2024/06/17 23:22
对于进程间通信,之前一直是用管道进行实现。比如父子进程间使用pipe,无血缘关系的进程可以使用fifo。从来没有想过使用共享内存,为什么呢?大家还记得这本书吧《Unix环境高级编程》,上面讲解了关于共享内存的操作,说实话,太麻烦了,真的不好用(有好多繁杂的接口,比如shmget, shmat,shmdt,chmctl等)。现在好了,基于POSIX标准的共享内存操作变得及其简单,总共就几个接口可供调用,已经变得像操作普通文件一样简单!
新的标准的接口如下:
POSIX 为创建、映射、同步和取消共享内存段提供五个入口点:
shm_open()
:创建共享内存段或连接到现有的已命名内存段。这个系统调用返回一个文件描述符。shm_unlink()
:根据(shm_open()
返回的)文件描述符,删除共享内存段。实际上,这个内存段直到访问它的所有进程都退出时才会删除,这与在 UNIX 中删除文件很相似。但是,调用shm_unlink()
(通常由原来创建共享内存段的进程调用)之后,其他进程就无法访问这个内存段了。mmap()
:把共享内存段映射到进程的内存。这个系统调用需要shm_open()
返回的文件描述符,它返回指向内存的指针。(在某些情况下,还可以把一般文件或另一个设备的文件描述符映射到内存。对这些操作的讨论超出了本文的范围;具体方法请查阅操作系统的mmap()
文档。)munmap()
:作用与mmap()
相反。msync()
:用来让共享内存段与文件系统同步 — 当把文件映射到内存时,这种技术有用。
使用共享内存的过程是,用 shm_open()
创建内存段,用 write()
或 ftruncate()
设置它的大小,用 mmap()
把它映射到进程内存,执行其他参与者需要的操作。当使用完时,原来的进程调用 munmap()
和 shm_unlink()
,然后退出。
怎么样?简单吧,就像文件操作一样,打开,映射得到一个指针,对指针操作,然后撤销映射,关闭!
下面给出两段示例代码,以示用来进行无血缘关系的进程间通信
- #include <sys/file.h>
- 6 #include <sys/mman.h>
- 7 #include <fcntl.h>
- 8 #include <sys/stat.h>
- 9 #include <sys/wait.h>
- 10 #include "util.h"
- 11
- 12 void error_and_die(const char *msg) {
- 13 perror(msg);
- 14 exit(EXIT_FAILURE);
- 15 }
- 16
- 17 int main()
- 18 {
- 19 int ret;
- 20 const size_t region_size = sysconf(_SC_PAGE_SIZE);
- 21 const char *string = "This is a test for share memory!/n";
- 22 int fd = shm_open(SHARE_MEMORY, O_CREAT | O_TRUNC | O_RDWR, 0666);
- 23 if (-1 == fd)
- 24 {
- 25 error_and_die("shm_open");
- 26 }
- 27
- 28 ret = ftruncate(fd, region_size);
- 29 if (ret)
- 30 {
- 31 error_and_die("ftruncate");
- 32 }
- 33
- 34 void *ptr = mmap(0, region_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0);
- 35 if (ptr == MAP_FAILED)
- 36 {
- 37 error_and_die("mmap");
- 38 }
- 39
- 40 close(fd);
- 41 //*(int *)ptr = 0x55aa;
- 42 memcpy(ptr, string, (strlen(string) + 1));
- 43
- 44 sleep(10);
- 45
- 46 ret = munmap(ptr, region_size);
- 47 if (ret)
- 48 error_and_die("munmap");
- 49
- 50 ret = shm_unlink(SHARE_MEMORY);
- 51 if (ret)
- 52 error_and_die("shm_unlink");
- 53 return 0;
- 54
- 55
- 56 }
- 1 #include <stdio.h>
- 2 #include <string.h>
- 3 #include <stdlib.h>
- 4 #include <unistd.h>
- 5 #include <sys/file.h>
- 6 #include <sys/mman.h>
- 7 #include <fcntl.h>
- 8 #include <sys/stat.h>
- 9 #include <sys/wait.h>
- 10 #include "util.h"
- 11
- 12 void error_and_die(const char *msg) {
- 13 perror(msg);
- 14 exit(EXIT_FAILURE);
- 15 }
- 16
- 17 int main()
- 18 {
- 19 int ret;
- 20 const size_t region_size = sysconf(_SC_PAGE_SIZE);
- 21 int fd = shm_open(SHARE_MEMORY, O_CREAT | O_RDWR, 0666);
- 22 if (-1 == fd)
- 23 {
- 24 error_and_die("shm_open");
- 25 }
- 26
- 27 ret = ftruncate(fd, region_size);
- 28 if (ret)
- 29 {
- 30 error_and_die("ftruncate");
- 31 }
- 32
- 33 void *ptr = mmap(0, region_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0);
- 34 if (ptr == MAP_FAILED)
- 35 {
- 36 error_and_die("mmap");
- 37 }
- 38
- 39 close(fd);
- 40
- 41
- 42 printf("%s", (char *)ptr);
- 43 ret = munmap(ptr, region_size);
- 44 if (ret)
- 45 error_and_die("munmap");
- 46
- 47 ret = shm_unlink(SHARE_MEMORY);
- 48 if (ret)
- 49 error_and_die("shm_unlink");
- 50
- 51 return 0;
- 52 }
代码很简单,唯一注意的地方是,第二个文件中shm_open的时候O_TUNC参数要去掉,否则内存又被截断为0,读不到东西的。
- Linux下基于POSIX标准的共享内存操作示例
- Linux下基于POSIX标准的共享内存操作示例
- Linux下基于POSIX标准的共享内存操作示例
- Linux下基于POSIX标准的共享内存操作示例
- posix 基于共享内存
- posix 基于文件的共享内存
- Posix共享内存区的基本操作
- Linux下共享内存示例
- linux下共享内存(shm)使用示例
- Linux下共享内存简单程序示例
- linux——posix标准下的信号量
- linux posix 读写锁+共享内存demo
- Linux进程通信之POSIX共享内存
- linux网络编程之POSIX共享内存
- Linux进程通信之POSIX共享内存
- Linux进程通信之POSIX共享内存
- Linux IPC实践(10) --Posix共享内存
- Linux IPC实践(10) --Posix共享内存
- Linux 中 RPM 命令参数使用详解
- SwitchTest3
- 如何安装驱动程序?
- JAXP对XML的DOM解析(增删改查)
- WARN com.opensymphony.xwork2.ognl.OgnlValueStack异常的解决办法
- Linux下基于POSIX标准的共享内存操作示例
- SwitchTest1
- 关于循环删除某元素的方法
- 用Nginx做反向代理实现负载均衡
- ListView拖动时背景变为黑色的问题
- jxl导出excel标题乱码
- “即插即用”型外设
- Asp.net 替换THML标签
- 高级语言程序设计(一)试题