您的位置:首页 > 运维架构 > Linux

进程通信程序整理---消息队列(Linux)

2017-12-09 21:00 363 查看
#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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: