曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 7341|回复: 0
打印 上一主题 下一主题

[进程] msgrcv | 读消息队列

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34395
跳转到指定楼层
楼主
发表于 2009-9-3 14:13:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
功能:读取队列消息

原型
#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);
参数说明
      msqid : 消息队列描述符
      msgp : 读取的消息存储到 msgp 指向的消息结构中
      msgsz : 消息缓冲区的大小
      msgtyp : 为请求读取的消息类型
      msgflg : 操作表置位。msg 可以为 IPC_NOWAIT, IPC_EXCEPT, IPC_NOERROR 3 个常量。这些值的意义分别是: IPC_NOWAIT , 如果没有满足条件的消息,调用立即返回,此时错误码为 ENOMSG ; IPC_EXCEPT, 与 msgtyp 配合使用,返回队列中的第一个类型不为 msgtyp 的消息;IPC_NOERROR ,如果队列中满足的消息内容大于所请求的 msgsz 字节,则把该消息截断,截断部分将被丢弃。
调用 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 结束进程退出读取。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-5-4 01:03 , Processed in 0.083094 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表