#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#define MSGKEY 123 //定义一个键值,通过键值找到所对应的消息队列
struct msgbuf //定义消息缓冲区的内容
{
long mtype; //消息类型
char mtext[100]; //消息文本
};
int main()
{
int msgid,ret;
struct msgbuf buf; //定义一个结构体变量,作为消息缓冲区
pid_t pid;
msgid = msgget(MSGKEY,IPC_CREAT|IPC_EXCL); //创建一个新的消息队列,如果消息队列已存在,则会产生错误
if(-1 == msgid)
{
perror("msgget");
exit(1); //如果创建失败,报出错误类型并返回
}
pid = fork();//创建进程
if(-1 == pid)
{
perror("fork");
exit(1);
}
else if(0 == pid) //此子进程将消息发送到另一个程序的父进程中
{
while(1)
{
memset(&buf,0,sizeof(buf)); //初始化缓冲区中的内容
scanf("%s",buf.mtext);
buf.mtype = 1; //设置消息类型
//msgsnd()将一个新的消息写入队列
ret = msgsnd(msgid,&buf,sizeof(buf.mtext),0); //第一个参数为消息队列的识别码;第二个参数为指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息;第三个参数为消息的大小;第四个参数为消息的类型,=0 则返回队列的最早的一个消息。>0,则返回其类型为mtype的第一个消息。<0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息。
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
if(!strncmp(buf.mtext,"bye",3))
{
buf.mtype = 2; //发送bye后此子进程会关闭,但父进程还在,所以此处7行,用来关闭父进程,避免僵尸进程
ret = msgsnd(msgid,&buf,sizeof(buf.mtext),0);
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
break;
}
}
}
else //此父进程用于接收另一个程序的子进程发送过来的消息
{
while(1)
{
memset(&buf,0,sizeof(buf));
ret = msgrcv(msgid,&buf,sizeof(buf.mtext),2,0); //注意:接受的消息类型必须为2,也就是另一个程序子进程发送的消息类型,上面的子进程发送的消息类型为1
if(-1 == ret)
{
perror("msgrcv");
exit(1);
}
if(!strncmp(buf.mtext,"bye",3))
{
kill(pid,SIGKILL); //收到后bye,父进程会关闭,但是子进程还在,所以要杀死子进程,避免孤儿进程
break;
}
printf("read :%s\n",buf.mtext);
}
waitpid(pid,NULL,0); //等待子进程结束,收尸
}
msgctl(msgid,IPC_RMID,NULL);//删除消息队列,方便下次程序再次运行
return 0;
}
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <signal.h>
#define MSGKEY 123 //定义一个键值,通过键值找到所对应的消息队列
struct msgbuf //定义消息缓冲区的内容
{
long mtype; //消息类型
char mtext[100]; //消息文本
};
int main()
{
int msgid,ret;
struct msgbuf buf; //定义一个结构体变量,作为消息缓冲区
pid_t pid;
msgid = msgget(MSGKEY,0); //打开键值相同的消息队列
if(-1 == msgid)
{
perror("msgget");
exit(1); //如果打开失败,报出错误类型并返回
}
pid = fork(); //创建进程
if(-1 == pid)
{
perror("fork");
exit(1);
}
else if(0 == pid) //此子进程将消息发送到另一个程序的父进程中
{
while(1)
{
memset(&buf,0,sizeof(buf)); //初始化缓冲区中的内容
scanf("%s",buf.mtext);
buf.mtype = 2; //设置消息类型
//msgsnd()将一个新的消息写入队列
ret = msgsnd(msgid,&buf,sizeof(buf.mtext),0); //第一个参数为消息队列的识别码;第二个参数为指向消息缓冲区的指针,此位置用来暂时存储发送和接收的消息;第三个参数为消息的大小;第四个参数为消息的类型,=0 则返回队列的最早的一个消息。>0,则返回其类型为mtype的第一个消息。<0,则返回其类型小于或等于mtype参数的绝对值的最小的一个消息。
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
if(!(strncmp(buf.mtext,"bye",3)))
{
buf.mtype = 1; //发送bye后此子进程会关闭,但父进程还在,所以此处7行,用来关闭父进程,避免僵尸进程
ret = msgsnd(msgid,&buf,sizeof(buf.mtext),0);
if(-1 == ret)
{
perror("msgsnd");
exit(1);
}
break;
}
}
}
else //此父进程用于接收另一个程序的子进程发送过来的消息
{
while(1)
{
memset(&buf,0,sizeof(buf));
ret = msgrcv(msgid,&buf,sizeof(buf.mtext),1,0); //注意:接受的消息类型必须为2,也就是另一个程序子进程发送的消息类型,上面的子进程发送的消息类型为1
if(-1 == ret)
{
perror("msgrcv");
exit(1);
}
if(!strncmp(buf.mtext,"bye",3))
{
kill(pid,SIGKILL); //收到后bye,父进程会关闭,但是子进程还在,所以要杀死子进程,避免孤儿进程
break;
}
printf("read another :%s\n",buf.mtext);
}
waitpid(pid,NULL,0); //等待子进程结束,收尸
}
return 0;
}
执行结果:
第一个程序执行 read :hello 第二个程序执行 hello
world read another :world
bye