曲径通幽论坛

标题: msgrcv | 读消息队列 [打印本页]

作者: beyes    时间: 2009-9-3 14:13
标题: msgrcv | 读消息队列
功能:读取队列消息

原型
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
ssize_t msgrcv(int msqid, void *msgp, size_t msgsz, long msgtyp, int msgflg);
参数说明
调用 msgrcv 函数的时候,成功则返回读出消息的实际字节数,否则返回 -1 。常见的错误码有: E2BIG ,表示消息的长度大于 msgsz ; EDIRM ,表示消息队列已被删除;EINVAL  ,说明 msqid 无效或小于 0 。

测试代码
#include <stdio.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>

#define  BUF_SIZE    256
#define  PROJ_ID    32
#define     PATH_NAME    "."

int main()
{
    /*用户自定义消息缓冲区*/
    struct mymsgbuf {
        long msgtype;
        char ctrlstring [BUF_SIZE];
    } msgbuffer;

    int     qid;
    int    msglen;
    int    msgkey;

    /*取键值*/
    if ((msgkey = ftok (PATH_NAME, PROJ_ID)) == -1) {
        perror ("ftok error!\n");
        exit (1);
    }

    /*获取消息队列标识符*/
    if ((qid = msgget (msgkey, IPC_CREAT|0660)) == -1) {
        perror ("ftok error!\n");
        exit (1);
    }
   
    msglen = sizeof (struct mymsgbuf) - 4;
    if (msgrcv (qid, &msgbuffer, msglen, 3, 0) == -1) {    /*读取数据*/
        perror ("msgrcv error!\n");
        exit (1);
    }
   
    printf ("Get message %s\n", msgbuffer.ctrlstring);
   
    return 0;
}

先用 ipcs 看以下内核中有几条消息队列:
------ Message Queues --------
key                  msqid      owner      perms      used-bytes   messages   
0x20086001      0          beyes       660           512                      2      
因为之前执行过两次写消息队列程序,所以现在内核中有 2 条消息。总共占据了 512 个字节。

现在执行上面的程序:
beyes@linux-beyes:~/C/queue> ./rcvmsg.exe
Get message Hello message queue

读出了一条!再看一下所剩的消息情况:
------ Message Queues --------
key                     msqid      owner      perms      used-bytes   messages   
0x20086001     0              beyes      660             256                  1    
      
可以看到,上面已经剩下 1 条消息,所剩下的字节数为 256 。

再执行上面程序读取一下:
beyes@linux-beyes:~/C/queue> ./rcvmsg.exe
Get message Hello message queue
....
------ Message Queues --------
key                msqid      owner      perms      used-bytes   messages   
0x20086001    0          beyes       660             0                     0   
由输出可见,消息已经被全部读取。

假如此时再运行 rcvmsg.exe 读取一次,由于程序里设置的 msgflg 标志为 0 ,所以会因读不到消息而被阻塞,这是可以 ctrl + c 结束进程退出读取。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2