父进程在内核空间创建了一个共享内存,通过fork函数,父子进程通过fork函数继承了shmid,所以父子进程可以对内核中同一个对象操作,刚开始父进程不断往对象里写,然后开始发信号SIGUSR1给子进程,让子进程读。对于子进程来说,刚开始睡眠,等待父进程写,然后被内核唤醒,读共享内存。此时父进程开始睡眠,当子进程读完后,将父进程唤醒,父进程唤醒后继续写……一直循环(父子进程都通过shmat映射到自己的空间)
代码开始执行时,因为父进程要等待从键盘接收信号,所以父子进程都是S+在后台睡眠状态
#include"stdio.h"
#include"sys/types.h"
#include"sys/shm.h"
#include"signal.h"
#include"unistd.h"
#include"stdlib.h"
#include"string.h"
void myfun(int signum)
{
return;
}
int main(int argc,char *argv[])//从命令行输入3个参数,ipcrm -m pid号
{
int shmid;
int key;
char *p;
int pid;
shmid=shmget(IPC_PRIVATE,128,IPC_CREAT | 0777);
if(shmid <0)
{
printf("创建共享内存失败\n");
return -1;
}
printf("创建共享内存成功 shmid=%d\n",shmid);
pid=fork();//创建进程pid
if(pid >0)//这是父进程
{
signal(SIGUSR2,myfun);//处理函数,因为默认是终止,去处理子进程发过来的xh
p=(char *)shmat(shmid,NULL,0);
if(p==NULL)
{
printf("父进程映射失败\n");
return -2;
}
while(1)
{
printf("父进程开始写\n");
fgets(p,128,stdin);
kill(pid,SIGUSR1);//给内核发信号去告诉子进程去读
pause();//等待子进程读
}
}
if(pid==0)
{
signal(SIGUSR1,myfun);//去处理父进程发过来的xh
p=(char *)shmat(shmid,NULL,0);
if(p==NULL)
{
printf("子进程映射失败\n");
return -3;
}
while(1)//循环读
{
pause();//等待父进程写,当信号被内核唤醒后开始读
printf("子进程开始读data:%s",p);
kill(getppid(),SIGUSR2);//读完了也要给内核发信号告诉父进程读完了
}
}
shmdt(p);
shmctl(shmid,IPC_RMID,NULL);
system("ipcs -m");
return 0;
}
来源:CSDN
作者:嵌嵌我爱你
链接:https://blog.csdn.net/qq_43849025/article/details/104312235