共享存储区机制进程通信
编程实现生产者和消费者共享存储区功能。生产者随机产生10个整型数据,写入共享存储区;消费者读出数据,并进行平方和平方根运算后输出。使用系统调用shmget()、shmat()、sgmdt()、shmctl()等, 实现程序。
共享存储区机制进程通信,用linux实现
- 写回答
- 好问题 0 提建议
- 追加酬金
- 关注问题
- 邀请回答
-
1条回答 默认 最新
- 偷拨网线的william 2022-05-31 11:54关注
享内存是进程间通信最有用的方式,也是最快的IPC形式。共享内存是说:同一块内存被映射到多个进程的地址空间。但是共享内存并不提供同步机制,因此需要互斥锁或者信号量。使用共享内存唯一需要注意的是:当前如果有进程正在向共享内存写数据,则在写入完成以前,别的进程不应当去读、写共享内存。
共享内存最大的优点就是快。由system V演变而来的内存共享相关函数。目前Linux对system V的共享内存方式支持的比较好。在高版本的Linux内核上,我们有更多的方式来完成共享存储。嵌入式开发板搭载的低版本内核的Linux操作系统基本上都是不支持POSIX标准的内存共享的,只能使用system V的内存共享方式。system V是通过映射特殊文件系统shm中的文件实现内存共享的。通过shmget获得或者创建一个IPC共享内存,并返回这块内存相应的标识符。同时会初始化内核维护的一个数据结构shmid_kernel.当然还会在shm文件系统之中创建一个不属于任何进程的文件。shmid_kernel这个结构体之中的最重要的一个区域是shm_file。它存储被映射文件的地址。
如果多个进程的公共祖先对mmap指定了MAP_SHARED标志,则这些进程共享此存储区。一个简单的例子如下。
#include #include #include #include #include #include #include int main() { int num = 7777777; int fd = open("/dev/zero",O_RDWR); if (-1 == fd) { perror("open zero fail"); exit(1); } int *p = mmap(0,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (MAP_FAILED == p) { perror("mmap fail"); exit(1); } close(fd); pid_t pid = fork(); if (0 == pid) { num = 233; *p = 666; } if (0 < pid) { wait(NULL); printf("*p = %d\n",*p); printf("num = %d\n",num); } if (-1 == pid) { perror("fork fail"); exit(1); } return 0; }
在子进程中更改了存储映射区域的值为666,也更改了num变量的值。让子进程先运行,父进程后运行,打印输出的结果如下。
对于存储映射区域,父子进程是共享的;对于变量,父子进程是独立的。 使用zero文件的优点是mmap函数的第二个参数len可以指定任意长度,而无需关心zero文件的大小。
Linux除了使用zero以外,它还提供了一种称为匿名映射的方式。这种方式需要在使用mmap的时候指定MAP——ANON标志,并将文件描述符设置为-1。更改上面的程序如下。
#include #include #include #include #include #include #include int main() { int num = 7777777; //注意这行代码和上面程序中的不同之处 int *p = mmap(0,sizeof(int),PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANON,-1,0); if (MAP_FAILED == p) { perror("mmap fail"); exit(1); } //close(fd); pid_t pid = fork(); if (0 == pid) { num = 233; *p = 666; } if (0 < pid) { wait(NULL); printf("*p = %d\n",*p); printf("num = %d\n",num); } if (-1 == pid) { perror("fork fail"); exit(1); } return 0; }
运行结果是一致的。
本回答被题主选为最佳回答 , 对您是否有帮助呢?解决 无用评论 打赏 举报
悬赏问题
- ¥20 西门子S7-Graph,S7-300,梯形图
- ¥50 用易语言http 访问不了网页
- ¥50 safari浏览器fetch提交数据后数据丢失问题
- ¥15 matlab不知道怎么改,求解答!!
- ¥15 永磁直线电机的电流环pi调不出来
- ¥15 用stata实现聚类的代码
- ¥15 请问paddlehub能支持移动端开发吗?在Android studio上该如何部署?
- ¥20 docker里部署springboot项目,访问不到扬声器
- ¥15 netty整合springboot之后自动重连失效
- ¥15 悬赏!微信开发者工具报错,求帮改