我在习惯线程编程时遇到了问题。我试图用互斥锁和锁来构建一个构造。但我需要boost :: condition_variable ::等待两个锁作为参数。但两个锁没有等待功能。
有没有人给我一个提示,或者我的方法完全错了?
我的目标是
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
...
}
}
答案 0 :(得分:1)
我不确定你想要实现的目标,一般来说,你应该避免在多个重叠的锁下操作。
但是,通常,为了避免死锁,您只需使用一致的锁定顺序。非成员lock
函数可以帮助解决这个问题:
以避免死锁的方式锁定以未指定且不确定的顺序作为参数提供的可锁定对象。从具有相同互斥(或其他可锁定对象)的多个线程以不同顺序同时调用此函数是安全的,没有死锁风险。如果对提供的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);
}
这是未经测试的,但可能会帮助您
答案 1 :(得分:0)
您可以在allBufferLock.unlock
和wait
之前手动呼叫lock
。但要注意,多个互斥锁的嵌套锁很容易导致死锁,如果在其他地方它们也都会被锁定。在获得另一个之前解锁一个会更安全,例如,如果可能,请internalBufferLock
代替allBufferLock
。