进程间通信-消息队列

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

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 1024
struct 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 1024
struct 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);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值