内核资料收集 POSIX消息队列
0. 一般性描述
POSIX标准(IEEE Std 1003.1-2001)基于消息队列定义了一个IPC机制, 就是POSIX消息队列. 它与System V IPC消息队列具有许多优点:
a. 更简单的基于文件的应用接口
b. 完全支持消息优先级
c. 完全支持消息到达异步通知, 这通过信号或线程创建实现
d. 用于阻塞发送与接收操作的超时机制
1. POSIX消息队列的库函数
mq_open()
mq_close()
mq_unlink()
mq_send()
mq_timedsend()
mq_receive()
mq_timedreceive()
mq_notify()
mq_getattr()
mq_setattr()
2.函数使用
a. 调用mq_open()库函数打开一个POSIX消息队列.函数的第一个参数是一个指定队列名字的字符串,这与文件名类似,而且必须以"/"开始. 该库函数接收一个open()系统调用的标志集: O_RDONLY, O_WRONLY, O_RDWR, O_CREAT, O_EXCL和O_NONBLOCK(用于阻塞发送与接收).应用可以通过指定一个O_CREAT标志来创建一个新的POSIX消息队列. mq_open()函数返回一个队列描述符, 与open()系统调用返回的文件描述符类似.
b. POSIX队列打开后, 可以通过库函数mq_send()/mq_receive()来发送与接收消息,并传递给它们mq_open()返回的队列描述符作为参数. 应用也可以通过mq_timedsend()/mq_timedreceive()指定应用程序等待发送与接收操作完成所需要的最长时间.
c. 除了在mq_receive()上阻塞,或者如果O_NONBLOCK标志位则继续在消息队列上轮询外,还可以通过执行mq_notify()库函数建立异步通知机制. 实际上当一个消息插入空队列时,应用可以要求: 要么给定指定进程发出信号,要么创建一个新线程
d. 最后,当应用使用完消息队列, 它调用mq_close()库函数, 传给它队列描述符. 注意,这个函数并不删除队列,这与close()系统调用不会删除文件一样. 要删除队列, 应用需要调用mq_unlink()函数.
3. Linux2.6中, POSIX消息队列引入了一个叫mqueue的特殊文件系统,每个现存队列在其中都有一个相应的索引节点. 内核提供几个系统调用,
mq_open()/mq_unlink()/mq_timedsend/mq_timedreceive()/mq_notify()/mq_getsetattr().
这些系统调用对应前面的库函数. 这些系统调用透明地对mqueue文件系统的文件进行操作,而大部分工作交由VFS层处理. 例如, 内核不提供mq_close()函数,而实际上返回给应用的队列描述符是一个文件描述符,因此mq_close()的工作由close()系统调用来做.
mqueue特殊文件系统不能安装在系统目录树中.但是如果安装了,用户可以通过使用文件系统根目录中的文件来创建POSIX消息队列,也可以读入相应文件来得到队列的有关信息.最后,应用可以使用select()/poll()获得队列状态变化的通知.
每个队列有一个mqueue_inode_info()描述符,它包括有inode对象, 该对象与mqueue特殊文件系统的一个文件相对应. 当POSIX消息队列系统调用接收一个队列描述符作为参数时,它就调用VFS的fget()函数计算出对应文件对象的地址.然后,系统调用得到mqueue文件系统中文件的索引节点对象. 最后,就可以得到该索引节点对象所对应的mqueue_inode_info描述符地址.
队列中挂起消息被收集到mqueue_inode_info描述符中的一个单向链表. 每个消息由一个msg_msg类型的描述符来表示, 这与System V IPC中使用的消息描述符是完全一样的
阅读(1998) | 评论(0) | 转发(0) |