我在Linux上使用Posix Message Queues。基本上,我有多個線程通過調用mq_timedreceive
來接收來自同一隊列的消息。我是否應該在由多個線程執行時同步mq_timedreceive調用?
如果同時運行多個線程且隊列不是空的,我保證消息不會被多次接收(即消息不會傳遞給多個線程)嗎?可以肯定的是,我可以將接收與一個互斥鎖同步,但是如果可能的話,我想避免這個鎖。我閱讀了所有手冊頁(man mq_overview(3)
),但沒有發現任何明確的內容。
在此先感謝。
我在Linux上使用Posix Message Queues。基本上,我有多個線程通過調用mq_timedreceive
來接收來自同一隊列的消息。我是否應該在由多個線程執行時同步mq_timedreceive調用?
如果同時運行多個線程且隊列不是空的,我保證消息不會被多次接收(即消息不會傳遞給多個線程)嗎?可以肯定的是,我可以將接收與一個互斥鎖同步,但是如果可能的話,我想避免這個鎖。我閱讀了所有手冊頁(man mq_overview(3)
),但沒有發現任何明確的內容。
在此先感謝。
內核爲你鎖定。
看在IPC/mqueue.c實現:
SYSCALL_DEFINE5(mq_timedreceive, mqd_t, mqdes, char __user *, u_msg_ptr,
size_t, msg_len, unsigned int __user *, u_msg_prio,
const struct timespec __user *, u_abs_timeout)
{
...
struct mqueue_inode_info *info;
...
filp = fget(mqdes);
if (unlikely(!filp)) {
ret = -EBADF;
goto out;
}
inode = filp->f_path.dentry->d_inode;
...
spin_lock(&info->lock);
if (info->attr.mq_curmsgs == 0) {
if (filp->f_flags & O_NONBLOCK) {
spin_unlock(&info->lock);
...
} else {
msg_ptr = msg_get(info);
inode->i_atime = inode->i_mtime = inode->i_ctime =
CURRENT_TIME;
/* There is now free space in queue. */
pipelined_receive(info);
spin_unlock(&info->lock);
ret = 0;
}
每個mqueue中有一個自旋鎖,這是檢查新郵件之前獲得的。
last else(pipelined_receive)是消息出列的地方。這受到info-> lock的保護,所以兩個線程無法獲得相同的消息。
本手冊頁介紹了它相當不錯:
http://pubs.opengroup.org/onlinepubs/009604499/functions/mq_receive.html
如果有多個線程在等待時,一個消息到達一個空隊列和優先級調度選項支持接收消息,那麼應選擇等待時間最長的最高優先級線程來接收消息。否則,未指定哪個等待線程收到該消息。
這允許您使用POSIX消息隊列來實現生產者/消費者線程。
我瀏覽了'ipc/mqueue.c'文件,但是我不確定鎖'lock'是否確實阻止將消息發送到多個接收者。你能詳細說明你的答案嗎? – 2012-03-05 11:32:54