2012-03-01 106 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消息队列来实现生产者/消费者线程。

相关问题