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、思维导图