加入收藏 | 设为首页 | 会员中心 | 我要投稿 应用网_丽江站长网 (http://www.0888zz.com/)- 科技、建站、数据工具、云上网络、机器学习!
当前位置: 首页 > 服务器 > 搭建环境 > Unix > 正文

UNIX环境高级编程:system V消息队列

发布时间:2016-05-17 11:34:23 所属栏目:Unix 来源:网络整理
导读:unix早期通信机制中的信号能够传送的信息量有限,管道则只能传送无格式字节流,这远远是不够的。 消息队列(也叫报文队列)客服了这些缺点: 消息队列就是一个

1.msgget函数

msgget函数用于创建一个新的消息队列或访问一个已存在的消息队列。

#include <sys/msg.h>  
int msgget(key_t key,int oflag);

返回值是一个整数标识符,其他三个msg函数就用它来指代该队列。它是基于指定的key产生的,而key即可以是ftok的返回值,也可以是常值IPC_PRIVATE。

oflag是读写权限值得组合。它还可以与IPC_CREAT或IPC_CREAT | IPC_EXCL按位或,IPC_NOWAIT --- 读写消息队列要求无法得到满足时,不阻塞。

当创建一个新消息队列时,msqid_ds结构的如下成员被初始化。

(1)msg_perm结构的uid和cuid成员被设置成当前进程的有效用户ID,gid和cgid成员被设置成当前进程的有效组ID。

(2)oflag中的读写权限位存放在msg_perm.mode中。

(3)msg_qnum,msg_lspid,msg_lrpid,msg_stime和msg_rtime被置为0.

(4)msg_ctime被设置成当前时间。

(5)msg_qbytes被设置成系统限制值。

huangcheng@ubuntu:~$ ipcs -q  ----查看消息队列  
      
------ Message Queues --------  
key        msqid      owner      perms      used-bytes   messages

2.msgsnd函数

使用msgget函数打开一个消息队列后,我们使用msgsnd往其上放置一个消息。

#include <sys/msg.h>  
int msgsnd(int msgid,const void *ptr,size_t length,int flag);

其中msqid是由msgget返回的标识符。ptr是一个结构指针,该结构具有如下模板,它定义在<sys/msg.h>中。

struct msgbuf {  
    long mtype;       /* message type, must be > 0 */
    char mtext[1];    /* message data */
};

msgsnd的length参数以字节为单位指定待发送消息的长度。这是位于长整数消息类型之后的用户自定义数据的长度(注意:不包括消息类型)。该长度可以是0.

flag参数既可以是0,也可以是IPC_NUWAIT。IPC_NOWAIT标志使得msgsnd调用非阻塞:如果没有存放新消息的可用空间(即消息队列已满),该函数马上返回。这个条件发生的情形包括:

(1)在指定的队列中已有太多的字节(对于该队列的msqid_ds结构中的msg_qbytes值);

(2)在系统范围存在太多的消息。

如果这两个条件中有一个存在,而且IPC_NUWAIT标志已指定,msgsnd就返回一个EAGAIN错误。如果这两个条件有一个存在,但是IPC_NUWAIT标志未指定,那么调用线程被投入睡眠直到:

(1)具备存放新消息的空间;

(2)由msqid标志的消息队列从系统中删除(这种情况下返回一个EIDRM错误);

(3)调用线程被某个捕获的信号所中断(这种情况下返回一个EINTR错误)。

3.msgrcv函数

使用msgrcv函数从某个消息队列中读取一个消息。

#include <sys/msg.h>  
ssize_t msgrcv(int msqid,void *ptr,size_t lengh,long type,int flag);

其中ptr参数指定所接收消息的存放位置。跟msgsnd一样,该指针指向紧挨在真正的消息数据之前返回的长整数类型字段。

length指定了由ptr指向的缓冲区中数据部分的大小。这是该函数能返回的最大数据量。该长度不包括长整数类型字段。

type指定希望从所给定的队列中读出什么样的消息。

(1)如果type为0,那就返回该队列中的第一个消息,既然每个消息队列都是作为一个FIFO链表维护的,因此type为0指定返回该队列中最早的消息。

(2)如果type大于0,那就返回其类型值为type的第一个消息。

(3)如果type小于0,那就返回其类型小于或等于type参数的绝对值的消息中类型值最小的第一个消息。

msgrcv的flag参数指定所请求类型的消息不在所指定的队列中时该做何处理。在没有消息可得的情况下,如果设置了flag中的IPC_NOWAIT位,msgrcv函数就立即返回一个ENOMSG错误。否则,设置了flag为0,调用者被阻塞到下列某个事件发生为止:

(1)有一个所请求类型的消息可获取;

(2)由msqid标志的消息队列从系统中删除(这种情况下返回一个EIDRM错误);

(3)调用线程被某个捕获的信号所中断(这种情况下返回一个EINTR错误)。

flag参数中另有一位可以指定:MSG_NOERROR。当所接收消息的真正数据部分大于length参数时,如果设置了该位,msgrcv函数就只是截短数据部分,而不返回错误。否则,ms_grcv返回一个E2BIC错误。

成功返回时,msgrcv返回的是所接收消息中数据的字节数。它不包括也通过ptr参数返回的长整数消息类型所需的几个字节。

(编辑:应用网_丽江站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读