无限等待条件变量

时间:2019-09-26 14:54:21

标签: c++ multithreading deadlock condition-variable

简化的目标是强制在3个不同的线程中一个接一个地调用3个成员函数(线程A调用F :: first,线程B F :: second,线程C F :: third)。

为了获得执行线程的顺序,我使用了1个条件变量和2个布尔值来指示第一线程和第二线程是否完成了工作。

在代码中:

std::mutex mtx;
std::condition_variable cv;
bool firstPrinted = false;
bool secondPrinted = false;

class F {
public:    
    void first(std::function<void()> printFirst) {
        std::unique_lock<std::mutex> lck(mtx);
        std::cout << "first\n";
        printFirst();
        firstPrinted = true;
        cv.notify_one();
    }

    void second(std::function<void()> printSecond) {
        std::unique_lock<std::mutex> lck(mtx);
        std::cout << "second\n";
        cv.wait(lck, []() { return firstPrinted; });
        printSecond();
        secondPrinted = true;
        cv.notify_one();
    }

    void third(std::function<void()> printThird) {
        std::unique_lock<std::mutex> lck(mtx);
        std::cout << "third\n";
        cv.wait(lck, []() { return secondPrinted; });
        printThird();
    }
};

auto first = []() {
    std::cout << "1";
};
auto second = []() {
    std::cout << "2";
};
auto third = []() {
    std::cout << "3";
};
F f;
std::thread A(&F::first,  &f, first);
std::thread B(&F::second, &f, second);
std::thread C(&F::third,  &f, third);
A.join(); B.join(); C.join();

现在让我们考虑这种情况:

线程A不会首先启动-无论第一个启动线程是B还是C,它们都阻塞(等待)直到得到通知(B阻塞直到A通知,C阻塞直到B通知)

当第一个启动线程为C时,将出现无限等待(或可能死锁!?),这总是产生以下输出:

third
second
first
...and stalling here

从理论上讲,这不会发生,因为在线程C中调用cv.wait会解锁互斥锁,从而使线程B能够运行,而线程B又会等待(因为条件未变为真),因此它也会解锁锁定的互斥锁线程A首先开始,最后应该进入关键部分并通知B。

  1. 什么是导致程序停止的调用路径?

  2. 我想念什么细微差别?

如果我在上述想法上有误,请纠正我。

1 个答案:

答案 0 :(得分:4)

std::condition_variable::notify_one()将唤醒一个线程,等待condition_variable。如果有多个线程正在等待,则将选择一个线程。它将唤醒,重新获取其谓词的锁定检查。如果该谓词仍为false,它将返回其等待状态,并且通知实际上丢失了。

当运行first的线程最后执行时,这就是这里发生的情况。到达notify_one时,将有两个线程在等待condition_variable。如果它通知运行third的线程,则该谓词仍将返回false。该线程将唤醒,无法通过谓词测试,然后返回等待状态。您的进程现在没有正在运行的线程,并且已冻结。

解决方案是使用std::condition_variable::notify_all()。此函数唤醒所有个正在等待的线程,这些线程将一次重新锁定mutex并检查自己的谓词。