作业:使用消息队列实现两个进程间通信
编程代码:使用父子进程实现通信
msgsnd.c
#include <myhead.h>
//定义自定义函数用于接收僵尸进程
void handler(int signo){
if(signo==SIGCHLD){
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
//定义存储消息队列信息结构体类型
struct msgbuf{
long mtype; //消息类型
char mtext[1024]; //消息正文
};
//宏定义消息正文大小
#define MSGSZ (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//使用消息队列实现两个进程间相互通信
if(signal(SIGCHLD,handler)==SIG_ERR){
perror("signal error");
return -1;
}//用于与SIGCHLD信号绑定
//1.创建一个key值
key_t key=ftok("/",'k');
if(key==-1){
perror("ftok error");
return -1;
}
//2.创建一个消息队列
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid==-1){
perror("msgget error");
return -1;
}
//创建一个子进程
pid_t pid=fork();
if(pid>0){//执行父进程
//3.父进程存放消息类型1数据
struct msgbuf buf;//用于存储消息
while(1){
printf("请输入消息队列类型1消息类型>>");
scanf("%ld",&buf.mtype);
getchar();//吸收垃圾字符
printf("请输入消息队列类型1消息正文");
fgets(buf.mtext,MSGSZ,stdin);
buf.mtext[strlen(buf.mtext)-1]='\0';//将\n转为\0
msgsnd(msqid,&buf,MSGSZ,0);//将信息存放于消息队列中
printf("消息队列类型1数据已存放\n");
if(strcmp(buf.mtext,"quit")==0){//结束循环
break;
}
}
}else if(pid==0){//执行子进程
//4.子进程读取消息类型2数据
struct msgbuf buf;//用于存储消息
while(1){
//从消息队列中读取数据
msgrcv(msqid,&buf,MSGSZ,2,0);//2表示从消息类型2读取数据,0表示阻塞读取
printf("消息队列类型2数据已读取,正文为:%s\n",buf.mtext);
if(strcmp(buf.mtext,"quit")==0){
break;
}
}
exit(EXIT_SUCCESS);//结束子进程
}else{
perror("fork error");
return -1;
}
//5.删除队列
if(msgctl(msqid,IPC_RMID,NULL)==-1){
perror("msgctl error");
return -1;
}
return 0;
}
msgrcv.c
#include <myhead.h>
//定义自定义函数用于接收僵尸进程
void handler(int signo){
if(signo==SIGCHLD){
while(waitpid(-1,NULL,WNOHANG)>0);
}
}
//定义存储消息队列信息结构体类型
struct msgbuf{
long mtype; //消息类型
char mtext[1024]; //消息正文
};
//宏定义消息正文大小
#define MSGSZ (sizeof(struct msgbuf)-sizeof(long))
int main(int argc, const char *argv[])
{
//使用消息队列实现两个进程间相互通信
if(signal(SIGCHLD,handler)==SIG_ERR){
perror("signal error");
return -1;
}//用于与SIGCHLD信号绑定
//1.创建一个key值
key_t key=ftok("/",'k');
if(key==-1){
perror("ftok error");
return -1;
}
//2.创建一个消息队列
int msqid=msgget(key,IPC_CREAT|0664);
if(msqid==-1){
perror("msgget error");
return -1;
}
//创建一个子进程
pid_t pid=fork();
if(pid>0){//执行父进程
//3.父进程存放消息类型2数据
struct msgbuf buf;//用于存储消息
while(1){
printf("请输入消息队列类型2消息类型>>");
scanf("%ld",&buf.mtype);
getchar();//吸收垃圾字符
printf("请输入消息队列类型2消息正文");
fgets(buf.mtext,MSGSZ,stdin);
buf.mtext[strlen(buf.mtext)-1]='\0';//将\n转为\0
msgsnd(msqid,&buf,MSGSZ,0);//将信息存放于消息队列中
printf("消息队列类型2数据已存放\n");
if(strcmp(buf.mtext,"quit")==0){//结束循环
break;
}
}
}else if(pid==0){//执行子进程
//4.子进程读取消息类型1数据
struct msgbuf buf;//用于存储消息
while(1){
//从消息队列中读取数据
msgrcv(msqid,&buf,MSGSZ,1,0);//1表示从消息类型1读取数据,0表示阻塞读取
printf("消息队列类型1数据已读取,正文为:%s\n",buf.mtext);
if(strcmp(buf.mtext,"quit")==0){
break;
}
}
exit(EXIT_SUCCESS);//结束子进程
}else{
perror("fork error");
return -1;
}
return 0;
}
运行结果:
思维导图: