进程间通信-消息队列

来源:互联网 发布:剪切一半的数据丢失了 编辑:程序博客网 时间:2024/06/05 04:29

消息队列是消息的链表,存储在内核中,由消息队列标识出标识。

msgget用于创建一个新队列或打开一个现有队列

#include<sys/msg.h>int msgget(key_t key,int flag)返回值:若成功,返回消息队列ID;若出错,返回-1

msgsnd将新消息添加到队列尾端,每个消息包含一个正的长整型类型的字段,一个非负的长度以及实际数据字节数,所有这些都在讲消息添加到队列时,传送给msgsnd。

#include<sys/msg.h>int msgsnd(int msgid,const void* ptr,size_t nbytes,int flag)返回值:若成功,返回0;若出错,返回-1

ptr参数指向一个长整型数,它包含了正的整形消息类型,其后紧接着的是消息数据。若发送的最长消息是512字节,则可定义下列结构

struct mymsg{    long mtype;    char mtext[512];};

ptr就是一个指向mymsg结构的指针。

msgrcv从队列中取用消息

#include<sys/msg.h>ssize_t msgrcv(int msgid,void* ptr,size_t nbytes,long type,int flag);返回值:若成功,返回消息数据部分长度;若出错,返回-1

和msgsnd一样,ptr指向一个长整形数,其后紧跟着的是存储在实际消息数据的缓存区,nbytes指定数据缓存区的长度。若返回的消息长度大于nbytes,而且在flag中设置了MSG_NOERROR位,则该消息会被截断。如果没有设置这一标志,而消息又太长,则出错返回E2BIG(消息仍留在队列中)。

参数type可以指定想要哪一种消息
type==0 返回消息队列中的第一个消息
type>0 返回消息队列中消息类型为type的第一个消息
type<0 返回消息队列中消息类型小于等于type绝对值的消息,如果这种消息有若干个,则取类型值最小的消息。

msgctl函数对队列执行多种操作

#include<sys/msg.h>int msgctl(int msgid,int cmd,struct msgid_ds* buf);返回值:若成功,返回0;若出错,返回-1

cmd 参数指定msgid指定的队列要执行的命令
IPC_STAT 取次队列的msgid_ds结构,并将它存放在buf指向的结构中
IPC_SET 将字段msg_perm.uid、msg_perm.gid、msg_perm.mode和msg_qbytes从buf指向的结构复制到与这个消息队列相关的msgid_ds结构中。
IPC_RMID 从系统中删除该消息队列以及仍在该队列中的所有数据。

下面是利用消息队列进行进程间通信的例子

//msgsend.c#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<sys/msg.h>#include<errno.h>#define MAXLEN 1024struct mymsg{    long mtype;    char mtext[MAXLEN];};int main(){    int msgid;    char buf[MAXLEN];    int n;    int len;    struct mymsg data;;    if((msgid=msgget((key_t)1234,0666|IPC_CREAT))<0)   //创建消息队列    {        fprintf(stderr,"msgset error:[%s]\n",strerror(errno));        exit(1);    }    while((fgets(buf,MAXLEN,stdin))!=NULL)    //从标准输入读取数据    {        data.mtype=1;        len=strlen(buf);        strncpy(data.mtext,buf,len);        if((n=msgsnd(msgid,(void*)&data,len,0))<0)     //发送到消息队列        {            fprintf(stderr,"msgsnd error:[%s]\n",strerror(errno));            exit(1);        }    }}
//msgrcv.c#include<stdio.h>#include<stdlib.h>#include<unistd.h>#include<string.h>#include<errno.h>#include<sys/msg.h>#define MAXLEN 1024struct mymsg{    long mtype;    char mtext[MAXLEN];};int main(){    char buf[MAXLEN];    int n;    int msgid;    struct mymsg data;    int type=1;    if((msgid=msgget((key_t)1234,0666|IPC_CREAT))<0)   //打开一个消息队列    {        fprintf(stderr,"msgget error:[%s]\n",strerror(errno));        exit(1);    }    while((n=msgrcv(msgid,(void*)&data,MAXLEN,type,0))>0)    //从消息队列接收数据    {        strncpy(buf,data.mtext,n);        write(STDOUT_FILENO,buf,n);    }    if(msgctl(msgid,IPC_RMID,0)<0)    //关闭消息队列    {        fprintf(stderr,"msgctl(IPC_RMID) error:[%s]\n",strerror(errno));        exit(1);    }    exit(0);}
原创粉丝点击