2012-03-01 61 views
4

我在Linux上使用Posix Message Queues。基本上,我有多個線程通過調用mq_timedreceive來接收來自同一隊列的消息。我是否應該在由多個線程執行時同步mq_timedreceive調用?

如果同時運行多個線程且隊列不是空的,我保證消息不會被多次接收(即消息不會傳遞給多個線程)嗎?可以肯定的是,我可以將接收與一個互斥鎖同步,但是如果可能的話,我想避免這個鎖。我閱讀了所有手冊頁(man mq_overview(3)),但沒有發現任何明確的內容。

在此先感謝。

回答

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的保護,所以兩個線程無法獲得相同的消息。

+0

我瀏覽了'ipc/mqueue.c'文件,但是我不確定鎖'lock'是否確實阻止將消息發送到多個接收者。你能詳細說明你的答案嗎? – 2012-03-05 11:32:54

2

本手冊頁介紹了它相當不錯:

http://pubs.opengroup.org/onlinepubs/009604499/functions/mq_receive.html

如果有多個線程在等待時,一個消息到達一個空隊列和優先級調度選項支持接收消息,那麼應選擇等待時間最長的最高優先級線程來接收消息。否則,未指定哪個等待線程收到該消息。

這允許您使用POSIX消息隊列來實現生產者/消費者線程。

相關問題