文章目录

  • 共享内存和信号量实现进程间通信
    • 题目
    • 思路
    • 一、写程序
    • 二、读程序
    • 三、运行结果
    • 总结

共享内存和信号量实现进程间通信

题目

通过共享内存和信号量实现进程间通信,其中A进程读入指定路径的文件,每次将一行文件信息保存到共享内存中并等待其他进程将数据读走,直至文件结束;B、C进程为父子进程,并发互斥的读取缓冲区信息并显示,然后再将缓冲区清空,直至接收到“quit”后,父子进程相继退出。

思路

写程序先申请一块共享内存,再打开文件,逐行读取文件内容到缓冲区并写入到共享内存。
读程序创建一个子进程,父子进程互斥访问共享内存并输出信息到显示器。
为了保证这个过程中信息读、写操作的正确性,需要通过信号量限制各个进程对共享内存的访问。写程序和读程序之间进行同步,读程序的父子进程之间进行互斥。

一、写程序

部分核心代码如下:

 struct Poem{char verse[96];};//定义要绑定到共享内存上的数据结构FILE *fp;int shmid;struct Poem *poem;char data[96];//定义缓冲区sem_t*sem;//同步信号量1sem_t*semm;//同步信号量2key_t shmkey;//定义IPCkeyshmkey=ftok("declaimer.c",0);//获取IPCkeyshmid=shmget(shmkey,1024,0666|IPC_CREAT);   //创建共享内存poem=(struct Poem *)shmat(shmid,0,0);//绑定共享内存sem=sem_open("asemofpoem",O_CREAT,0644,1);//创建并初始化有名信号量semm=sem_open("asemofwrite",O_CREAT,0644,1);fp = fopen("poem.txt","r");//打开文件do{sem_wait(semm);//等待读进程读取完毕post后继续进行读写操作memset(data, 0, 96);//缓冲区清零memset(poem->verse, 0, 96);//结构体变量清零if(fgets(data, 96, fp) == NULL)//读取一行文件内容并判断是否结束{sem_post(sem);break;}strncpy(poem->verse, data,strlen(data)-1);//复制一行到缓冲区sem_post(sem);//读程序中的进程获得sem信号量后可以进行读取sleep(1);}while(strncmp(data,"quit",4)!=0);fclose(fp);//关闭文件

这里似乎没有必要定义一个结构体来绑定共享内存,但是参考教材上的例子就照着用了,其实换成用字符数组直接绑定共享内存应该也是可以的。

二、读程序

部分核心代码如下:

 struct Poem{char verse[96];};//定义读取数据结构struct Poem *poem;pid_t pid;//进程号sem_t*sem;//同步信号量1sem_t*semm;//同步信号量2sem_t*mutex;//互斥信号量int shmid;key_t shmkey;shmkey=ftok("declaimer.c",0);//获取IPCkeysem=sem_open("asemofpoem",0,0644,0);semm=sem_open("asemofwrite",0,0644,0);mutex=sem_open("asemofread",O_CREAT,0644,1);//定义互斥信号量shmid=shmget(shmkey,0,0666);poem=(struct Poem *)shmat(shmid,0,0);//绑定共享内存pid=fork();//创建子进程do{sem_wait(mutex);//互斥访问临界资源sem_wait(sem);  //等待写进程写入数据if(pid==0)//根据进程ID输出信息printf("\n子进程读取:%s \n",poem->verse);elseprintf("\n父进程读取:%s \n",poem->verse);if (strncmp(poem->verse, "quit", 4)== 0) //检测到结束标志{sem_post(sem);sem_post(mutex);break;}sem_post(semm);//读取完成,写程序获取sem后可继续写入sem_post(mutex);//释放访问临界资源信号量} while(1);

三、运行结果

写程序没有定义向标准输出流输出数据,命令行窗口不显示任何信息:

username:~/$ ./declaimer

读程序父子进程交替读取写程序写入共享内存中的信息并进行显示,读到quit停止:

username:~/$  ./audient 父进程读取:君不见黄河之水天上来,奔流到海不复回。 子进程读取:君不见高堂明镜悲白发,朝如青丝暮成雪。 父进程读取:君不见高堂明镜悲白发,朝如青丝暮成雪。 子进程读取:人生得意须尽欢,莫使金樽空对月。 父进程读取:天生我材必有用,千金散尽还复来。 子进程读取:烹羊宰牛且为乐,会须一饮三百杯。 父进程读取:岑夫子,丹丘生,将进酒,杯莫停。 子进程读取:与君歌一曲,请君为我倾耳听。 父进程读取:钟鼓馔玉不足贵,但愿长醉不愿醒。 子进程读取:古来圣贤皆寂寞,惟有饮者留其名。 父进程读取:陈王昔时宴平乐,斗酒十千恣欢谑。 子进程读取:主人何为言少钱,径须沽取对君酌。 父进程读取:五花马、千金裘,呼儿将出换美酒,与尔同销万古愁。  子进程读取:quit 父进程读取:quit 

总结

题目涉及到多进程间的同步和互斥问题,可以看作是生产者-消费者问题的变种,因为在读程序(消费者)中存在着多个进程,需要在原有的生产者-消费者系统的消费者程序设置互斥信号量保证多个进程之间互斥访问共享内存,如此就可以保证对共享内存读写操作的正确性。

共享内存和信号量实现进程间通信相关推荐

  1. Linux(信号,进程间通信)共享内存,信号量,消息队列

    信号(signal) 1.1 什么是信号? 信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式 1.2 信号的来源 硬件 [1] 用户在终端按下某些键时,终端驱动程序会发送信号给前台进程 ct ...

  2. 进程间通信之分别用共享内存和信号量实现卖票

    利用共享内存实现的卖票系统: 利用flag来保证同一时间只有一个程序使用内存,使用结束还原. #include <stdio.h> #include <sys/ipc.h> # ...

  3. php多进程共享数据库,PHP多进程环境下通过共享内存与信号量实现资源共享

    PHP多进程环境下通过共享内存与信号量实现资源共享 目前工作环境,由于一些原因,不能使用swoole,和其他多进程的管理组件.但是项目中有大量的功能必须通过多进程来实现.面对这也不能,那也不能的困境, ...

  4. Linux进程通信的四种方式——共享内存、信号量、无名管道、消息队列|实验、代码、分析、总结

    Linux进程通信的四种方式--共享内存.信号量.无名管道.消息队列|实验.代码.分析.总结 每个进程各自有不同的用户地址空间,任何一个进程的全局变量在另一个进程中都看不到,所以进程之间要交换数据必须 ...

  5. c++ fork 进程时 共享内存_c/c++ Linux 进程间通信------共享内存

    1. 什么是共享内存 共享内存(Shared Memory),指两个或多个进程共享一个给定的存储区.进程可以将同一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是 ...

  6. 进程间共享内存(信号量实现同步)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://yongjiuzhizhen.blog.51cto.com/7980250/132 ...

  7. linux共享内存与信号量的使用

    1.使用共享内存在两个进程中传值 2.使用信号量做同步控制. #include <unistd.h> #include <stdlib.h> #include <stdi ...

  8. Linux共享内存和信号量,Linux共享内存和信号量的实例(2)

    nbsp;    //SLEEP 3秒,等待消费者进程执行完毕 printf("Poducer if over\n"); exit(0); } else { /*  消费者A进程  ...

  9. linux学习---基于内存的IPC(共享内存,信号量数组,消息队列)

    常用的IPC分为两个类别,一是基于文件,而是基于内存 基于文件的分别有匿名管道,有名管道,普通的文件共享,socket文件 如果要看基于文件的IPC,请参考:http://blog.csdn.net/ ...

最新文章

  1. php 实现 pacs 系统,影像管理系统(PACS)
  2. 利用getLayoutParams()方法和setLayoutParams()方法
  3. 访谈Stuart Davidson:Skyscanner的持续交付推广
  4. JavaScript数组的API
  5. (Oracle学习笔记) Oracle体系结构
  6. Nancy 寄宿OWin
  7. c语言让数组地址对齐,C语言实现比特位数组在目标空间左右居中对齐三种方式...
  8. java的jdk是什么_什么是jdk?
  9. 理解 Nginx HTTP 代理, 负载均衡, Buffering, Caching
  10. C#常用操作类库一(验证类)
  11. 易筋SpringBoot 2.1 | 第十一篇:SpringBoot使用actuator
  12. MATLAB处理txt文档数据——以处理pscad输出数据为例
  13. 超市不同时段人流量统计分析
  14. 杭电acm2012 素数判定
  15. 浅析城市综合管廊配电结构
  16. 影视之观大秦帝国之裂变总结
  17. 2022-2028年中国幼儿园露天游乐设备行业市场专项调查及投资前景分析报告
  18. miRNA与 lncRNA的相互调控作用
  19. 微信签到积分换卷小程序(完整前后台)
  20. 学渣的刷题之旅 leetcode刷题 88. 合并两个有序数组

热门文章

  1. 浙大中控ECS700学习笔记二硬件I/O模块
  2. python的del方法_关于python:__ del__方法是什么,如何调用它?
  3. 机器人Scribit_飞檐走壁的艺术家 Scribit绘画机器人
  4. mysql vip的作用_MySQL用户与权限的管理
  5. 《游戏脚本的设计与开发》-(RPG部分)3.5 游戏背包和任务系统
  6. 【java之GUI设计】传说逐渐“退隐江湖”的java之GUI!
  7. 校二级计算机考试内容,计算机二级考试科目及内容有哪些
  8. Java版贪食蛇游戏
  9. 隐​藏​任​意​一​个​分​区​图​标​,​个​人​已​验​证​技​术​贴
  10. python 3.8.0安卓_Python3.8.0(32/64位)官方正式版_Python下载-PC9软件园