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

Linux下进程间通信之消息队列

2017-02-14 10:09 399 查看
    消息队列是进程间通信之一,当然还有其他通信方式:管道,有名管道,内存共享,套接字等,下面详细介绍消息队列的用法。

首先介绍几个函数

int msgctl(int msgid , ing cmd , struct msgid_ds *buf);

int msgget(key_t key , ingt msgflg);

int msgrcv(ing msgid , void* msg_ptr , size_t msg_sz , long int msgtype , int msgflg);

int msgsnd(int msgid , const void* msg_ptr , size_t msg_sz , int msgflg);

这些函数的作用跟共享内存和信号量的作用是相同的。

int msgctl(int msgid , ing cmd , struct msgid_ds *buf);: 控制函数,用来控制消息列队的关闭等。

int msgget(key_t key , ingt msgflg);用来创建一个消息列队

int msgrcv(ing msgid , void* msg_ptr , size_t msg_sz , long int msgtype , int msgflg);用来接收一个消息

int msgsnd(int msgid , const void* msg_ptr , size_t msg_sz , int msgflg);用来发送一个消息

下面来看一个具体的例子。在这个例子中,我们将在客户端中对消息进行接收,在接收完所有的消息后,删除消息列队。

在服务器中,我们将发送消息到消息列队中,直到遇到end结束符为止。

发送消息源程序,命名为msgsend.c

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/msg.h>

#define BUFSIZE 1024

struct msg_st
{
int msg_type;
char msg_buf[BUFSIZE];
};

int main(int argc, char *argv[])
{
int msgid;//定义消息队列id
key_t key;//唯一识别两通信的消息队列,要与接收方一致
struct msg_st msg_data;
char buffer[BUFSIZE];
int runnig = 1;

//消息队列是否创建成功
if((msgid = msgget(key = 1234, 0666 | IPC_CREAT)) == -1)
{
fprintf(stderr, "msgget failed with error:%d\n",errno);
exit(-1);
}

while(runnig)
{
//get some data
printf("enter some data:");
fgets(buffer,BUFSIZE,stdin);
msg_data.msg_type = 1;
strcpy(msg_data.msg_buf,buffer);

//send data
if(msgsnd(msgid, (void *)&msg_data, BUFSIZE, 0) == -1)
{
fprintf(stderr, "msgsend failed with error:%d\n",errno);
exit(-1);
}

//exit with end
if(strncmp(msg_data.msg_buf,"end",3) == 0)
{
runnig = 0;
}

}

if(msgctl(msgid,IPC_RMID,0) == -1)
{
fprintf(stderr, "msgctl failed with error:%d\n",errno);
exit(-1);
}

exit(0);

}


接收消息源程序,命名为 msgrcv.c

#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<errno.h>
#include<unistd.h>
#include<sys/msg.h>

#define BUFSIZE 1024

struct msg_st
{
int msg_type;
char msg_buf[BUFSIZE];
};

int main(int argc, char *argv[])
{
int msgid;
key_t key;
struct msg_st msg_data;
int msg_recv = 0;
int runnig = 1;

if((msgid = msgget(key = 1234, 0666 | IPC_CREAT)) == -1)
{
fprintf(stderr, "msgget failed with error:%d\n",errno);
exit(-1);
}

while(runnig)
{
if(msgrcv(msgid, (void *)&msg_data, BUFSIZE, msg_recv, 0) == -1)
{
fprintf(stderr, "msgrcv failed with error:%d\n",errno);
exit(-1);
}

//以end结束
printf("receive data: %s\n",msg_data.msg_buf);
if(strncmp(msg_data.msg_buf,"end",3) == 0)
{
runnig = 0;
}

}
//关闭消息队列
if(msgctl(msgid,IPC_RMID,0) == -1)
{
fprintf(stderr, "msgctl failed with error:%d\n",errno);
exit(-1);
}
exit(0);
}


消息队列的用法比较简单,大概分为以下几步:

1.定义一个结构体用来存放数据,msg_data和msg_type

2.定义消息队列id,创建消息队列 msgget(){}

3.消息队列接收和发送函数 msgrcv(){}和 msgsnd(){}

4.关闭消息队列 msgctl(){}

注意:在定义key_t key 的时候,发送和接收的key值要相同



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux 进程