将多个互斥体与条件变量一起使用
是否有一种机制可以让条件变量使用多个互斥体? 我在 Linux 中,pthreads 在 C++ 中。
在应用程序中,我需要 pthread_cond_wait() 以原子方式获取和释放两个互斥体(而不是一个),但该函数只接受一个。
我有一个名为 BlockingManager 的类,它有以下方法:
blockMeFor( pthread_cond_t* my_cond, pthread_mutex_t* my_lock, set<int> waitees);
我正在使用它,假设它像 pthread_cond_wait 一样获取/释放互斥体。
问题是,为了实现blockingManager,我也需要一个内部互斥体,并且这两个互斥体都应该以原子方式获取和释放。
这里有一个相关的讨论,它说等待多个互斥体会产生未定义的行为。 http://sourceware.org/ml/libc-help/2011-04 /msg00011.html
我面临的问题的生产者/消费者模型如下:
我们有多个客户端。 每个客户都有一些任务。 每个任务可能有多个先决条件(在同一客户端或其他客户端的任务之间)。 每个客户端都有一个消费者线程。 这些任务从一个生产者线程分配给客户端。 新分配的任务可能有资格在之前的任务之前完成。 有时可能没有任务要做,但如果有任务要做,至少应该完成一项。 (它应该是节省工作的)
我为每个消费者线程使用一个 condvar,一旦该线程没有任务需要完成,它就会阻塞。 condvar 可以由
- 分配新任务的生产者线程发出信号。
另一个消费者线程正在完成任务。
我为每个消费者使用一个互斥体来保护生产者和消费者之间的共享数据结构。消费者。 以及一个互斥体(内部互斥体)来保护多个消费者之间的共享数据结构。
Is there a mechanism to have a conditional variable use multiple mutexes?
I am in Linux and pthreads in C++.
In an application, I need two mutexes (instead of one) to be atomically acquired and released by pthread_cond_wait(), but the function only accepts one.
I have a class named BlockingManager and it has the method:
blockMeFor( pthread_cond_t* my_cond, pthread_mutex_t* my_lock, set<int> waitees);
and I am using it, assuming that it acquires/releases the mutex just like pthread_cond_wait.
The problem is that for implementing blockingManager I need an internal mutex too and both of these mutexes should be acquired and released atomically.
There is a somehow related discussion here, it says waiting for more than one mutex yields undefined behavior.
http://sourceware.org/ml/libc-help/2011-04/msg00011.html
A producer/consumer model for the problem I am facing follows:
We have multiple clients.
Each client has some tasks.
Each task probably has multiple prerequisites (either among the tasks of the same client or other clients).
Each client has one consumer thread.
The tasks are assigned to the clients from one producer thread.
The newly assigned task may be eligible to be done before the previous tasks.
There may be no task to be done at some moments, but if there is a task to be done, at least one should be done. (It should be work-conserving)
I am using one condvar per consumer thread and it would block once there is no task to be done for that thread.
The condvar may be signaled by either
The producer thread assigning a new task.
Another consumer thread finishing a task.
I am using one mutex per consumer to protect the shared data-structures between producer & consumer.
And one mutex (internal mutex) to protect the shared data-structures between multiple-consumers.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
在 C++11 中(如果您的编译器支持),您可以使用 std::lock 一次锁定两个互斥体(不会出现死锁)。您可以使用它来构建一个引用两个互斥锁的
Lock2
类。然后您可以使用std::condition_variable_any
等待Lock2
。这一切可能看起来像这样:如果您的编译器尚不支持这些工具,您可以在 boost 中找到它们。
In C++11 (if your compiler supports it) you can use
std::lock
to lock two mutexes at once (without deadlock). You can use this to build aLock2
class which references two mutexes. And then you can usestd::condition_variable_any
to wait on aLock2
. This all might look something like:If your compiler does not yet support these tools, you can find them in boost.