假设以下代码在单核处理器上运行:
#include <cstdio>
#include <boost/thread.hpp>
#include <boost/thread/condition.hpp>
#include "boost/date_time/posix_time/posix_time.hpp"
#include <deque>
#include <cstdlib>
#include <time.h>
std::deque<int> buffer;
boost::mutex bufferMutex;
boost::condition bufferHasSome;
boost::condition bufferEmpty;
void Reader()
{
boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
//read as fast as possible:
while(true)
{
while(buffer.size() <= 0) //1.1
{
bufferHasSome.wait(lock); //1.2
}
bufferMutex.lock();
for(int i = 0; i < buffer.size(); i++)
{
printf("%d\n", buffer.front());
buffer.pop_front();
}
bufferMutex.unlock();
//everything was read:
bufferEmpty.notify_one();
}
}
void Writer()
{
boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
int index = 0;
while(true)
{
//write portion:
for(int i = rand() % 5; i >= 0; i--)
{
bufferMutex.lock();
buffer.push_back(index);
bufferMutex.unlock(); //2.1
bufferHasSome.notify_one(); //2.2
index++;
boost::this_thread::sleep(boost::posix_time::milliseconds(rand() % 10));
}
//definetely wait while written portion will be read:
while(buffer.size() > 0)
{
bufferEmpty.wait(lock);
}
}
}
int main()
{
srand(time(NULL));
boost::thread readerThread(Reader);
boost::thread writerThread(Writer);
getchar();
return 0;
}
并且处理器在 Reader 线程内 1.1(其中 size = 0)之后停止,并切换到添加索引的 Writer( 2.1) 进入 buffer 并且 bufferHasSome 被通知(在 2.2)(但是没有人在等待它所以它是只是无效操作);然后处理器切换回 Reader 线程并开始(在 1.2)等待有人向 buffer 写入内容,但只有一个可以写入正在等待某人读取缓冲区。 这个程序在平均 150 次迭代后卡住 - 我认为这是因为这个。 我错过了什么?如何解决?
最佳答案
我在这里看到了几个问题。最重要的是,您在锁之外检查共享值(即 buffer.size())。其次,每个函数都有这些奇怪的互斥锁,它们什么都不做,因为它们不在线程之间共享。如果您在检查 buffer.size() 之前锁定 bufferMutex,然后等待 bufferMutex(这意味着您将解锁它,这是正确的,然后在通知线程时重新锁定它),我认为死锁威胁应该消失了。
关于c++ - C++/boost/thread 中可能出现死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5053432/