对一个条件变量使用多个互斥锁

Using more than one mutex with a conditional variable

本文关键字:条件 一个 变量      更新时间:2023-10-16

是否有一种机制可以让条件变量使用多个互斥体?我在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每个消费者线程,它会阻塞一旦没有任务要做的线程。可由

发出信号
  • 生产者线程分配新任务。

  • 另一个消费者线程正在完成一个任务。

我为每个消费者使用一个互斥锁来保护生产者之间的共享数据结构。消费者。和一个互斥锁(内部互斥锁)来保护多个消费者之间共享的数据结构。

在c++ 11中(如果您的编译器支持它),您可以使用std::lock一次锁定两个互斥锁(没有死锁)。您可以使用它来构建引用两个互斥锁的Lock2类。然后你可以用std::condition_variable_any来等待Lock2。这一切可能看起来像:

#include <mutex>
#include <condition_variable>
std::mutex m1;
std::mutex m2;
std::condition_variable_any cv;
class Lock2
{
    std::mutex& m1_;
    std::mutex& m2_;
public:
    Lock2(std::mutex& m1, std::mutex& m2)
        : m1_(m1), m2_(m2)
    {
        lock();
    }
    ~Lock2() {unlock();}
    Lock2(const Lock2&) = delete;
    Lock2& operator=(const Lock2&) = delete;
    void lock() {std::lock(m1_, m2_);}
    void unlock() {m1_.unlock(); m2_.unlock();}
};
bool not_ready() {return false;}
void test()
{
    Lock2 lk(m1, m2);
    // m1 and m2 locked
    while (not_ready())
        cv.wait(lk);  // m1 and m2 unlocked
    // m1 and m2 locked
}  // m1 and m2 unlocked

如果您的编译器还不支持这些工具,您可以在boost.

中找到它们。