4> 使用消息队列完成两个进程间相互通信
usr1代码:
#include <myhead.h> //定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[1024];//消息正文
};
#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)
int main(int argc, const char *argv[])
{//创建key值key_t key =0;if((key=ftok("./",'k'))==-1){perror("ftok error");return -1;}printf("ftok success key=%#x\n",key);//根据key值创建一个消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}printf("msgget success msqid =%d\n",msqid);pid_t pid=fork();//创建子进程if(pid>0)//父进程{struct msgbuf sbuf;sbuf.mtype=1;while(1){bzero(sbuf.mtext,sizeof(sbuf.mtext));//清空容器fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);//从终端获取消息正文sbuf.mtext[strlen(sbuf.mtext)-1]=0;//向消息队列中存放消息msgsnd(msqid,&sbuf,MSGSIZE,0);printf("usr1发送成功\n");if(strcmp(sbuf.mtext,"end")==0){kill(pid,SIGKILL);break;}}wait(NULL);}else if(pid==0)//子进程{struct msgbuf rbuf;while(1){bzero(rbuf.mtext,sizeof(rbuf.mtext));//清空容器//从消息队列中获取类型为2一个消息msgrcv(msqid,&rbuf,MSGSIZE,2,0);printf("收到的消息是类型%ld中的消息:%s\n",rbuf.mtype,rbuf.mtext);if(strcmp(rbuf.mtext,"end")==0){kill(getppid(),SIGKILL);break;}}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}
usr2代码:
#include <myhead.h>
///定义信号处理函数
void handler(int signo)
{if(signo == SIGCHLD){ wait(NULL);exit(EXIT_SUCCESS);}
}
//定义一个消息类型
struct msgbuf
{long mtype;//消息类型char mtext[1024];//消息正文
};#define MSGSIZE sizeof(struct msgbuf)-sizeof(long)int main(int argc, const char *argv[])
{//创建key值key_t key =0;if((key=ftok("./",'k'))==-1){perror("ftok error");return -1;}printf("ftok success key=%#x\n",key);//根据key值创建一个消息队列int msqid=-1;if((msqid=msgget(key,IPC_CREAT|0664))==-1){perror("msgget error");return -1;}printf("msgget success msqid =%d\n",msqid); struct msgbuf rbuf; struct msgbuf sbuf;sbuf.mtype=2;pid_t pid=fork();//创建进程if(pid>0)//父进程{signal(SIGCHLD,handler);while(1){bzero(sbuf.mtext,sizeof(sbuf.mtext));//清空容器fgets(sbuf.mtext,sizeof(sbuf.mtext),stdin);//从终端获取消息正文sbuf.mtext[strlen(sbuf.mtext)-1]=0;//向消息队列中存放消息:msgsnd(msqid,&sbuf,MSGSIZE,0);printf("usr2发送成功\n");if(strcmp(sbuf.mtext,"end")==0) {kill(pid,SIGKILL);break;}} }else if(pid==0)//子进程{while(1){bzero(rbuf.mtext,sizeof(rbuf.mtext));//清空容器//从消息队列中获取类型为1一个消息msgrcv(msqid,&rbuf,MSGSIZE,1,0);printf("usr2收到的消息是类型%ld中的消息:%s\n",rbuf.mtype,rbuf.mtext);if(strcmp(rbuf.mtext,"end")==0){break;}}//删除消息队列if(msgctl(msqid,IPC_RMID,NULL)!=0){perror("msgctl error");return -1;}exit(EXIT_SUCCESS);}else{perror("fork error");return -1;}return 0;
}
运行结果:
思维导图: