linux 消息队列


消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
①消息队列的创建与打开
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
int msgget(key_t key,int msgflg);
返回值:
– 如果成功,返回消息队列标识符
– 如果失败,则返回-1 
在以下两种情况下,该调用将创建一个新的消息队列:
– 如果没有消息队列与健值key相对应,并且msgflg中包含了IPC_CREAT标志位;
– key参数为IPC_PRIVATE;(其值为0)

②向消息队列中发送消息

原型:
int msgsnd(int msqid,struct msgbuf* msgp,int msgsz,int msgflg);

参数含义:
–msqid参数是消息队列标识符,它是由系统调用msgget返回的;
–msgp参数是指向消息缓冲区的指针;
– 参数msgsz中包含的是消息的字节大小,但不包括消息类型的长度(4个字节);
– 参数msgflg可以设置为0(此时为忽略此参数),或者使用IPC_NOWAIT。

返回值:
– 如果成功,返回值为0;
– 如果失败,返回值为-1

③从消息队列接收消息
函数形式:
intmsgrcv(intmsqid,structmsgbuf* msgp,int msgsz,long mtype,int msgflg);

参数含义:
– 第一个参数用来指定将要读取消息的队列;
– 第二个参数代表要存储消息的消息缓冲区的地址;
– 第三个参数是消息缓冲区的长度,不包括mtype的长度,它可以按照如下的方法计算:
msgsz=sizeof(structmymsgbuf)-sizeof(long);
– 第四个参数是要从消息队列中读取的消息的类型。如果此参数的值为0,那么队列中最长时间的一条消息将返回,而不论其类型是什么

返回值:
– 如果成功,则返回复制到消息缓冲区的字节数。
– 如果失败,则返回-1。
④消息队列控制

函数形式:
int msgctl(int msgqid,int cmd,struct msqid_ds* buf);


返回值:
– 如果成功,返回值为0;
– 如果失败,返回值为-1 
–cmd参数的取值:
– IPC_STAT   读取消息队列的数据结构msqid_ds,并将其存储在buf指定 的地址中。
– IPC_SET       设置消息队列的数据结构msqid_ds中的ipc_perm元素的值 。这个值取自buf参数。
–IPC_RMID 从系统内核中移走消息队列。/*write.msg.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512

struct message
{
    long msg_type;
    char msg_text[BUFSIZ];
};

int main(void)
{
    int qid;
     key_t key;
    int len;
    struct message msg;
    /*根据不同的路径和键值产生标准的key*/
    if((key=ftok(".",'a'))==-1)
     {
         perror("ftok");
         exit(1);
     }
    /*创建消息队列*/
    if((qid=msgget(key,IPC_CREAT|0666))==-1)
     {
         perror("msgget");
         exit(1);
     }
     printf("opened queue %d \n",qid);
    while(1)
     {
        /*写消息队列*/
         puts("Please enter the message to queue:");
        if((fgets((&msg)->msg_text,BUFSIZ,stdin))==NULL)
         {
             puts("no message");
             exit(1);
         }
         msg.msg_type=getpid();
         printf("message: %s   is sent!\n",(&msg)->msg_text);
         len=strlen(msg.msg_text);
        /*添加消息队列*/
        if(msgsnd(qid,&msg,len,0)<0)
         {
             perror("message posted");
             exit(1);
         }
     }
    /*从系统内核中移走消息队列*/
    if((msgctl(qid,IPC_RMID,NULL))<0)
     {
         perror("msgctl");
         exit(1);
     }
     exit(0);
}
/*read_msg.c*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#define BUFSIZ 512

struct message
{
    long msg_type;
    char msg_text[BUFSIZ];
};

int main(void)
{
    int qid;
     key_t key;
    int len;
    struct message msg;
    /*根据不同的路径和键值产生标准的key*/
    if((key=ftok(".",'a'))==-1)
     {
         perror("ftok");
         exit(1);
     }
    /*创建消息队列*/
    if((qid=msgget(key,IPC_CREAT|0666))==-1)
     {
         perror("msgget");
         exit(1);
     }
     printf("opened queue %d \n",qid);
    while(1)
     {
        /*读取消息队列*/
        if(msgrcv(qid,&msg,BUFSIZ,0,0)<0)
         {
             perror("msgrcv");
             exit(1);
         }
         printf("message : %s   is received!\n",(&msg)->msg_text);
     }
    /*从系统内核中移走消息队列*/
    if((msgctl(qid,IPC_RMID,NULL))<0)
     {
         perror("msgctl");
         exit(1);
     }
     exit(0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值