博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
IPC通信:Posix共享内存2
阅读量:5900 次
发布时间:2019-06-19

本文共 5192 字,大约阅读时间需要 17 分钟。

Posix共享内存区涉及两个步骤:

1、指定一个名字参数调用shm_open,以创建一个新的共享内存区对象或打开一个以存在的共享内存区对象。

2、调用mmap把这个共享内存区映射到调用进程的地址空间。传递给shm_open的名字参数随后由希望共享该内存区的任何其他进程使用。

相关函数:

1 shm_open()函数 2 功能:    打开或创建一个共享内存区 3 头文件:    #include 
4 函数原形: int shm_open(const char *name,int oflag,mode_t mode); 5 返回值: 成功返回0,出错返回-1 6 参数: 7 name 共享内存区的名字 8 oflag 标志位 9 mode 权限位10 11 参数解释:oflag参数必须含有O_RDONLY和O_RDWR标志,还可以指定如下标志:O_CREAT,O_EXCL或O_TRUNC.mode参数指定权限位,12 它指定O_CREAT标志的前提下使用。shm_open的返回值是一个整数描述字,它随后用作mmap的第五个参数。13 14 shm_unlink()函数15 功能: 删除一个共享内存区16 头文件: #include
17 函数原形: int shm_unlink(const char *name);18 参数: name 共享内存区的名字19 返回值: 成功返回0,出错返回-120 21 shm_unlink函数删除一个共享内存区对象的名字,删除一个名字仅仅防止后续的open,mq_open或sem_open调用取得成功。

示例代码:

1 /*shm_open.c创建共享内存区*/ 2 #include 
3 #include
4 #include
5 #include
6 7 int main(int argc,char **argv) 8 { 9 int shm_id;10 11 if(argc!=2)12 {13 printf("usage:shm_open
\n");14 exit(1);15 }16 shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);17 printf("shmid:%d\n",shm_id);18 shm_unlink(argv[1]);19 }

编译运行:

1 root@linux:/mnt/hgfs/C_libary# vi shm_open.c 2 root@linux:/mnt/hgfs/C_libary# gcc -o shm_open shm_open.c 3 /tmp/cceAejzp.o: In function `main': 4 shm_open.c:(.text+0x43): undefined reference to `shm_open' 5 shm_open.c:(.text+0x6c): undefined reference to `shm_unlink' 6 collect2: ld returned 1 exit status 7 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_open shm_open.c 8 root@linux:/mnt/hgfs/C_libary# ./shm_open shm_test 9 shmid:310 root@linux:/mnt/hgfs/C_libary#

相关函数2:

1 ftruncate()函数 3 功能:    调整文件或共享内存区大小 4 头文件:    #include 
5 函数原形: int ftruncate(int fd,off_t length); 6 参数: 7 fd 描述符 8 length 大小 9 返回值: 成功返回0,出错返回-110 11 当打开一个已存在的共享内存区对象时,我们可调用fstat来获取有关该对象的信息12 13 fstat()函数14 功能: 获得文件或共享内存区的信息15 头文件: #include
16 #include
17 #include
18 函数原形: int stat(const char *file_name,struct stat *buf);19 参数: 20 file_name 文件名21 buf stat结构22 返回值: 成功返回0,出错返回-123 24 对于普通文件stat结构可以获得12个以上的成员信息,然而当fd指代一个共享内存区对象时,只有四个成员含有信息。25 struct stat{26 mode_t st_mode;27 uid_t st_uid;28 gid_t st_gid;29 off_t st_size;30 };

示例代码:

1 /*shm_show.c显示共享区信息*/ 2 #include 
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 10 int main(int argc,char **argv)11 {12 int shm_id;13 struct stat buf;14 15 if(argc!=2)16 {17 printf("usage:shm_open
\n");18 exit(1);19 }20 shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/*创建共享内存*/21 printf("size :%d\n",buf.st_size); /*修改前共享内存区大小*/22 ftruncate(shm_id,100);/*修改共享内存的大小*/23 fstat(shm_id,&buf); /*把共享内存的信息记录到buf中*/24 printf("uid_t:%d\n",buf.st_uid); /*共享内存区所有者ID*/25 printf("git_t:%d\n",buf.st_gid); /*共享内存区所有者组ID*/26 printf("size :%d\n",buf.st_size); /*修改后共享内存区大小*/27 }

编译运行:

1 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_show shm_show.c 2 shm_show.c: In function ‘main’: 3 shm_show.c:20: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘__off_t’ 4 shm_show.c:25: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘__off_t’ 5  6 /* 内容来自互联网 7         有人提出来在sys/types.h里面加上 typedef long __off_t; typedef long __time_t;  8          9         小鱼我看了一下源文件,认为上面的说法还是有问题的,露了off_t和time_t10         #ifndef __off_t_defined 11         # ifndef __USE_FILE_OFFSET64 12         typedef __off_t off_t; 13         # else 14         typedef __off64_t off_t; 15         # endif 16         # define __off_t_defined 17         #endif  18         19         如果定义了__USE_FILE_OFFSET64 就把off_t定义为__off64_t ,否则定义为32位(传说中的大文件支持处理) 20         ------------------------------21         其实没必要casting。直接用%ld换掉%d就行了,因为是long int所以%d会抛警告的 22 */23 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_show shm_show.c24 root@linux:/mnt/hgfs/C_libary# 25 root@linux:/mnt/hgfs/C_libary# ./shm_show test26 size :498364827 uid_t:028 git_t:029 size :10030 root@linux:/mnt/hgfs/C_libary#

共享内存区的写入和读出

  前面我们介绍了mmap函数,下面我们就可以通过这些函数,把进程映射到共享内存区。然后我们就可以通过共享内存区进行进程间通信了。

示例代码:

1 /*shm_write.c写入/读出共享内存区*/ 2 #include 
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 10 int main(int argc,char **argv)11 {12 int shm_id;13 struct stat buf;14 char *ptr;15 16 if(argc!=2)17 {18 printf("usage:shm_open
\n");19 exit(1);20 }21 shm_id=shm_open(argv[1],O_RDWR|O_CREAT,0644);/*创建共享内存区*/22 ftruncate(shm_id,100);/*修改共享区大小*/23 fstat(shm_id,&buf);24 ptr=mmap(NULL,buf.st_size,PROT_READ|PROT_WRITE,MAP_SHARED,shm_id,0);/*连接共享内存区*/25 strcpy(ptr,"hello linux");/*写入共享内存区*/26 printf("%s\n",ptr);/*读出共享内存区*/27 shm_unlink(argv[1]);/*删除共享内存区*/28 }

编译运行:

1 root@linux:/mnt/hgfs/C_libary# gcc -lrt -o shm_write shm_write.c2 root@linux:/mnt/hgfs/C_libary# ./shm_write test3 hello linux4 root@linux:/mnt/hgfs/C_libary#

 

  至此进程间通讯内容先告一段落!

转载地址:http://vhhsx.baihongyu.com/

你可能感兴趣的文章
书摘—你不可不知的心理策略
查看>>
【博客话题】毕业——开始人生的艰苦历程
查看>>
2014.7.30-8.3日广大网友的提问解答(答问题的第2个工作周)
查看>>
Powershell管理系列(二十五)PowerShell操作之获取AD账号及邮箱信息
查看>>
android开发 更新升级安装到一半自动闪退
查看>>
Linux安装telnet
查看>>
linux 标准I/O (二)
查看>>
【高德地图API】从零开始学高德JS API(三)覆盖物——标注|折线|多边形|信息窗口|聚合marker|麻点图|图片覆盖物...
查看>>
IOS 消息机制(NSNotificationCenter)
查看>>
JAVA 设计模式 策略模式
查看>>
openstack nova修改实例路径,虚拟磁盘路径
查看>>
java.sql.SQLException: Lock wait timeout exceeded --转
查看>>
使用C#进行图像处理的几种方法(转)
查看>>
Ajax原理学习
查看>>
sap scriptfom 多语言翻译
查看>>
实现超级简单的bug管理系统
查看>>
Java集合中的AbstractMap抽象类
查看>>
图像滤镜艺术---(Lightleaks Filter)漏光滤镜
查看>>
[LeetCode] Find Anagram Mappings 寻找异构映射
查看>>
--Too small initial heap for new size specified
查看>>