利用Linux的共享内存通信机制实现两个进程间的通信

0. 相关博客

实现一个模拟的shell_ 一只博客-CSDN博客_操作系统实验模拟shellhttps://blog.csdn.net/qq_42276781/article/details/98521603实现一个管道通信程序_ 一只博客-CSDN博客_实现一个管道通信程序https://blog.csdn.net/qq_42276781/article/details/98523996利用Linux的消息队列通信机制实现两个线程间的通信_ 一只博客-CSDN博客_杭电操作系统实验三https://blog.csdn.net/qq_42276781/article/details/90672038

1. 利用Linux的共享内存通信机制实现两个进程间的通信

       编写程序sender,它创建一个共享内存,然后等待用户通过终端输入一串字符,并将这串字符通过共享内存发送给receiver;最后,它等待receiver的应答,收到应答消息后,将接收到的应答信息显示在终端屏幕上,删除共享内存,结束程序的运行。编写receiver程序,它通过共享内存接收来自sender的消息,将消息显示在终端屏幕上,然后再通过该共享内存向sender发送一个应答消息“over”(老师告知可以省略这步操作),结束程序的运行。选择合适的信号量机制实现两个进程对共享内存的互斥及同步使用。

2. 原代码

无bug,可正常运行

3. 图片识别结果

有bug,无法直接运行,调试改bug过程中可以加深代码理解

test4.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<semaphore.h>
#include<fcntl.h>
#include<sys/shm.h>
sem_t *w;//定义写的信号量 
int main(){
	pid_t pid;
	int  shm_id,x;
	char *shm_addr;
	char *name="writer";
	char buff [256];
	//初始化有名信号量 
	w=sem_open(name,O_CREAT,0666,1);
	
	//以下两行代码用以确保Write的初值为1,因为笔者在调试代码期间,有时Write的初值不为1 
	//如有需要可以使用这两行代码 
	/*sem_getvalue(w,&x);
	if(x==0) sem_post(w);*/
	 
	shm_id=shmget(IPC_PRIVATE,256,0666);
	if(shm_id<0){
		perror("shmget error");
		exit(1);
	}
	pid=fork();//创建子进程 
	if(pid<0){//创建失败 
		perror("fork error");
		exit(1);
	}
	else if(pid==0){//当前运行子进程 
		while(1){
			sem_wait(w);//申请写的权限 
			//把共享内存区对象映射到调用进程的地址空间
			//函数原型void *shmat(int shmid, const void *shmaddr, int shmflg)
			//具体参数含义参见https://baike.baidu.com/item/shmat 
			shm_addr=shmat(shm_id,0,0);
			if(shm_addr==(void *)-1){//映射失败 
				perror("child shmat error");
				sem_post(w);
				exit(1);
			}
			strcpy(buff,shm_addr);//将共享内存中的信息拷贝至buff 
			printf("child receive:%s",buff );
			//断开共享内存连接 
			//函数原型int shmdt(const void *shmaddr)
			//具体参数含义参见https://baike.baidu.com/item/shmat  
			if(shmdt(shm_addr)<0){
				perror("child shmdt");//断开连接失败,返回提示 
				sem_post(w);//释放写的权限 
				exit(1);
			}	
			sem_post(w);
			sleep(2); 
		}
	}
	else while(1){//当前运行父进程 
		sem_wait(w); 
		printf("parent send:");
		shm_addr=shmat(shm_id,(void *)0,0);
		if(shm_addr==(void *)-1){
			perror("parent shmat error"); 
			sem_post(w);
			exit(1);
		}
		fgets(buff,256,stdin);//读取键盘的一行输入到buff 
		if(!strncmp(buff,"exit",4)){
			sem_post(w);
			if (shmctl(shm_id,IPC_RMID,NULL)==-1){
				perror("shmctl :IPC_ RMID");
				sem_post(w);
				exit(1);
			}
			else{
				printf("-------end--------\n");
				sem_post(w);
				exit(0);
			}
		}
		else{
			//将buff写入共享内存 
			strncpy(shm_addr,buff,strlen(buff));
			//断开共享内存的连接 
			if(shmdt(shm_addr)<0){
				perror("parent shmdt");
				sem_post(w);
				exit(1);
			}
		        sem_post(w);
			sleep(3);
		}
	}
	return 0;
}	

4. 代码及实验报告获取

关注公众号,回复“进程管理”即可获取代码和实验报告

 

  • 3
    点赞
  • 54
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Toblerone_Wind

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值