linux应用程序编程之消息队列

作者在 2010-10-13 15:44:44 发布以下内容

消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。对消息队列有写权限的进程可以向中按照一定的规则添加新消息;对消息队列有读权限的进程则可以从消息队列中读走消息。
①消息队列的创建与打开
#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);
}

默认分类 | 阅读 1130 次
文章评论,共1条
变幻小子
2011-03-18 11:51
1
路过看看
游客请输入验证码
浏览48253次
文章分类