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. 代码及实验报告获取
关注公众号,回复“进程管理”即可获取代码和实验报告