Should I synchronize mq_timedreceive calls when executed by multiple threads?

I am using Posix Message Queues on Linux. Basically, I have several threads that receive messages from a single queue using mq_timedreceive calls.

If several threads are started at the same time, and the queue is not empty, I am sure that the message does not receive more than once (that is, the message is not delivered to several threads)?

Of course, I could synchronize the reception with the mutex, but if possible, I would like to avoid this lock. I read all the man pages ( man mq_overview(3) ) but did not find anything explicit.

Thanks in advance.

+4
source share
2 answers

The kernel does this lock for you.

Look at the implementation in 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; } 

Each mqueue has a spin lock, which is obtained before checking for new messages.

In the latter case (pipelined_receive) there is an error message. This is protected by the info-> lock, so neither of the two threads can receive the same message.

+3
source

This man page describes this pretty well:

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

If several messages are waiting to receive a message when the message enters an empty queue, and the priority scheduling parameter is supported, then the stream with the highest priority, which was the longest, is selected to receive the message. Otherwise, it is not indicated which waiting thread is receiving the message.

This allows the use of POSIX message queues to implement producer / consumer flows.

+2
source

Source: https://habr.com/ru/post/1399223/


All Articles