c++ - C++/boost/thread 中可能出现死锁

标签 c++ deadlock boost-thread

假设以下代码在单核处理器上运行:

#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/

相关文章:

c++ - 使用智能指针为大量对象创建多个索引

mysql - ActiveRecord3 死锁重试

C++ 重载和覆盖 - 无法使用类型为 '' 的右值初始化类型为 '' 的参数

java - 有关Java死锁情况的问题

unix - 内核 : Dealing with deadlocks in unix

c++ - boost::condition_variable.timed_wait 立即返回

c++ - Boost::thread::interrupt() 对于不同的中断点表现不同。为什么?

c++ - Boost.thread 代码在 Ubuntu 和 Windows 中呈现不同的行为

c++ - 为什么我不能将 this 指针显式传递给成员函数?

c++ - 在 boost::graph 中对 EdgeList 进行排序