消息队列(报文队列)能够克服早起UNIX通信机制的一些缺点。作为早起unix通信机制之一的信号能够传送的信息量有限,后来虽然POSIX 1003.1b在信号的实时性作了推广,使得信号在传递信息量方面有了相当程度的改进,但是信号着中国通信方式更像“即时”的通信方式,它要求接受信号的进程在某个时间范围内对信号做出反应,因此该信号最多在接受信号进程的声明周期才有意义,信号所传递的信息是接近于随进程持续的概念(process-persistent),管道是典型的随进程持续IPC,并且,只能传送无格式的字节流无疑会给应用程序开发带来不便,另外它的缓冲区大小也受到限制(linux/limits.h文件中的PIPE_BUF变量定义)。
消息队列就是一个消息的链表。可以把消息看作一个记录,具有特定的格式以及特定的优先级。每个消息队列有一个队列头,成为struct msg_queue,这个队列头描述了消息队列的key值,用户ID,组ID等信息,但它存在于内核中而结构体struct msqid_ds能够返回或设置消息队列的信息,这个结构体位于用户空间中,与msg_queue结构相似,消息队列允许一个或多个进程向他写入或读取消息,而且消息是按消息类型访问与写入(如果读队列使用的消息类型为0,则读取消息队列中的第一条消息,对于大于0和小于0的消息类型读取有其他含义,可通过man msgrcv手册查看)。消息读取后即在消息队列中删除。
对消息队列有写权限(S_IWUSR、GRP、OTH)的进程可以向其按照一定的规则添加消息;对消息队列具有读权限的进程可以读走消息,消息队列是随内核持续的,即当使用该消息队列的进程结束,或者已关闭该消息队列,该队列中的消息不会随之消失,只有在内核重新初始化,即计算机重启之后才会消失,因此成为内核的持续性,这点也是与管道和FIFO的区别。消息队列的另一个特性是,在某一个进程往消息队列写消息之前不需要另外某个进程在该消息队列上等待消息的到达,即不会像管道FIFO那样,如果往管道和FIFO写数据时,如果没有一个进程已经将读端打开,那么写操作会被阻塞。当然如果从消息队列读取数据时,消息队列为空时可以按设置的flag决定是否阻塞。
目前主要有两种类型的消息队列:POSIX消息队列以及系统V消息队列,系统V消息队列目前被大量使用。考虑到程序的可移植性,新开发的应用程序应尽量使用POSIX消息队列。
阅读(443) | 评论(0) | 转发(0) |