加速condition_variable等待多个锁定

boost condition_variable wait for multiple locks

本文关键字:锁定 等待 variable condition 加速      更新时间:2023-10-16

>我在习惯线程编程时遇到问题。我试图构建一个带有互斥锁和锁的构造。但是我需要提升::condition_variable::等待两个锁作为参数。但是两个锁没有等待功能。

有人给我提示吗,或者我的方法完全错误?

我的目标是

  • 允许并发 add((,将所有内容写入缓冲区
  • 工作线程运算符 ((((,存储缓冲值
  • 和一个 search((,在搜索之前等待工作线程

    class Archive
    {
        vector externalBuffer;
        vector swapBuffer;
        vector internalBuffer;
        boost::mutex externalBufferMutex;
        boost::mutex allBufferMutex;
        boost::condition_variable bufferIsFilledConditionVariable;
        void operator () ()
        {
            unique_lock allBufferLock(allBufferMutex);
            while(true)
            {
                {
                    unique_lock lock(externalBufferMutex);
                    while(buffer.empty())
                    {
                        bufferIsFilledConditionVariable.wait(...); // I should call it with two locks?
                    }
                    externalBuffer.swap(swapBuffer);
                }
                {
                    internalBuffer.swap(swapBuffer);
                    // store values from internalBuffer
                    ...
                    internalBuffer.clear();
                }
            }
        }
        void add(value) // pseudo code here
        {
            {
                lock_guard lock(externalBufferMutex);
                externalBuffer.push_back(value);
            }
            bufferIsFilledConditionVariable.notify_one();
        }
        // search will not be used concurrently with add()
        // it should just wait for the worker thread
        someReturnValue search()
        {
            unique_lock lock(allBufferMutex);
            // search here
            ...
        }
    }

我不确定您要实现的目标,一般来说,您应该避免在多个重叠的锁下进行操作。

但是,通常,为了避免死锁,您只需使用一致的锁顺序。非成员lock函数可以帮助实现以下方面:

  • http://www.boost.org/doc/libs/1_56_0/doc/html/thread/synchronization.html#thread.synchronization.lock_functions.lock_multiple

    未指定和不确定的顺序锁定作为参数提供的 Lockable 对象,以避免死锁。可以安全地从具有相同互斥锁(或其他可锁定对象(的多个线程以不同的顺序并发调用此函数,而不会有死锁的风险。如果提供的 Lockable 对象上的任何 lock(( 或 try_lock(( 操作引发异常,则该函数获取的任何锁都将在函数退出之前释放。

  • http://en.cppreference.com/w/cpp/thread/lock(适用于 C++11(

unique_lock lk_all(allBufferMutex,      boost::defer_lock);
unique_lock lk_ext(externalBufferMutex, boost::defer_lock);
boost::lock(lk_all, lk_ext);
while(internalBuffer.empty())
{
    lk_all.unlock();
    bufferIsFilledConditionVariable.wait(lk_ext);
    boost::lock(lk_all, lk_ext);
}

这是未经测试的,但可能会在路上帮助你

您可以在wait之前和之后lock手动调用allBufferLock.unlock。但请注意,多个互斥锁的嵌套锁很容易导致死锁,如果在其他地方它们也会被锁定。在获取另一个之前解锁一个会更安全,例如,如果可能的话,internalBufferLock而不是allBufferLock