1、用消息队列实现两个进程直接的通信
先输入的代码
#include<myhead.h>
//定义消息列队的结构体
struct msgbuf
{long mtype; //消息类型char mtext[1024]; //消息正文
};//宏定义正文的大小
#define MSGSZ (sizeof(struct msgbuf) - sizeof(long))//定义回收僵尸信号
void handler(int signo)
{//判断是否为SIGCHLD信号if(signo == SIGCHLD){while(waitpid(-1 , NULL ,WNOHANG)>0);}
}int main(int argc, const char *argv[])
{//11、当进程结束时进行回收将SIGCHLD信号非阻塞回收僵尸进程if(signal(SIGCHLD,handler)== SIG_ERR){perror("signal error");return -1;}//1、首先创建一个key值key_t key = ftok("/",'k');if(key == -1){perror("ftok error");return -1;}printf("key = %#x\n", key);//2、创建消息队列int msqid = msgget(key , IPC_CREAT|0664);if(msqid == -1){perror("msgger error");return -1;}//11、创建子进程pid_t pid = -1;pid = fork();if(pid > 0 ) //判断父进程 {//3、向消息队列中存放数据struct msgbuf buf1;while(1){printf("请输入消息类型>>>");scanf("%ld",&buf1.mtype);getchar(); //吸收回车printf("请输入消息正文>>>");fgets(buf1.mtext,MSGSZ,stdin); //从终端输入数据到正文中buf1.mtext[strlen(buf1.mtext)-1] = 0; //将回车换成'\0'//将消息存入消息队列msgsnd(msqid,&buf1,MSGSZ,0);printf("发送成功\n");if(strcmp(buf1.mtext , "quit") == 0) //输入的是quit 就结束{break;}}}if(pid == 0){//4、子进程读取子进程存入消息列队的数据struct msgbuf buf2;while(1){msgrcv(msqid,&buf2,MSGSZ,0,0); //接收子进程中buf2中的数据printf("收到消息为:%s\n", buf2.mtext);if(strcmp(buf2.mtext,"quit") == 0) {break;}}exit(EXIT_SUCCESS);}//删除消息列队if(msgctl(msqid,IPC_RMID,NULL)== -1){perror("msgctl error");return -1;}return 0;
}
2.后写入代码
#include<myhead.h>
//定义消息类型结构体
struct msgbuf
{long mtype; //消息类型char mtext[1024]; //消息正文
};
//宏定义正文大小
#define MSGSZ (sizeof(struct msgbuf) - sizeof(long))//定义回收僵尸信号
void handler(int signo)
{//判断是否为SIGCHLD信号if(signo == SIGCHLD){while(waitpid(-1 , NULL ,WNOHANG)>0);}
}int main(int argc, const char *argv[])
{//11、当进程结束时进行回收将SIGCHLD信号非阻塞回收僵尸进程if(signal(SIGCHLD,handler) == SIG_ERR){perror("signal error");return -1;}//1、创建一个key值key_t key = ftok("/",'k');if(key == -1){perror("ftok error");return -1;}printf("key = %#x\n", key);//2、创建消息队列int msqid = msgget(key , IPC_CREAT|0664);if(msqid == -1){perror("msgget error");return -1;}printf("msqid = %d\n", msqid);//创建子进程pid_t pid = -1;pid = fork();if(pid >0) //判断父进程:{//3、父进程读取父进程中消息列队中存入的数据struct msgbuf buf1;while(1){msgrcv(msqid,&buf1,MSGSZ,0,0); //接收父进程中的消息列队 buf1中的数据printf("收到消息为:%s\n",buf1.mtext);if(strcmp(buf1.mtext,"quit") == 0) //当接收到quit 时结束程序 {break;}}}if(pid == 0) //子进程向消息列队中存放数据{struct msgbuf buf2;while(1){printf("请输入消息类型>>>");scanf("%ld",&buf2.mtype); //将终端输入的数据类型写入数据类型中getchar(); //吸收回车printf("请输入消息正文>>>");fgets(buf2.mtext,MSGSZ,stdin); //从终端输入数据写入到正文buf2.mtext[strlen(buf2.mtext)-1] = 0; //将回车换成'\0'msgsnd(msqid,&buf2,MSGSZ,0);printf("发送成功\n");if(strcmp(buf2.mtext,"quit") == 0){break;}}exit(EXIT_SUCCESS);}//4、删除消息列队if(msgctl(msqid,IPC_RMID,NULL) == -1){perror("msgctl error");return -1;}return 0;
}
2、思维导图