gpt4 book ai didi

等待条件下的C++线程死锁

转载 作者:行者123 更新时间:2023-11-30 05:24:32 25 4
gpt4 key购买 nike

尝试扩展我之前的两个问题 Move operations for a class with a thread as member variableCall function inside a lambda passed to a thread

我不明白为什么执行 wait_for 的线程有时没有收到通知导致死锁。 Cppreference 在条件变量上说 http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one

The notifying thread does not need to hold the lock on the same mutex as the one held by the waiting thread(s); in fact doing so is a pessimization, since the notified thread would immediately block again, waiting for the notifying thread to release the lock.

MCVE,注释行解释了如果我持有锁会发生什么变化,但我不明白为什么:

#include <atomic>
#include <condition_variable>
#include <mutex>
#include <thread>

#include <iostream>

using namespace std;

class worker {
public:
template <class Fn, class... Args>
explicit worker(Fn func, Args... args) {
t = std::thread(
[&func, this](Args... cargs) -> void {
std::unique_lock<std::mutex> lock(mtx);
while (true) {
cond.wait(lock, [this]() -> bool { return ready; });
if (terminate) {
break;
}

func(cargs...);
ready = false;
}
},
std::move(args)...);
}

~worker() {
terminate = true;
if (t.joinable()) {
run_once();
t.join();
}
}

void run_once() {
// If i dont hold this mutex the thread is never notified of ready being
// true.
std::unique_lock<std::mutex> lock(mtx);
ready = true;
cout << "ready run once " << ready << endl;
cond.notify_all();
}

bool done() { return (!ready.load()); }

private:
std::thread t;
std::atomic<bool> terminate{false};
std::atomic<bool> ready{false};
std::mutex mtx;
std::condition_variable cond;
};

// main.cpp

void foo() {
worker t([]() -> void { cout << "Bark" << endl; });
t.run_once();
while (!t.done()) {
}
}

int main() {
while (true) {
foo();
}
return 0;
}

最佳答案

您需要一个内存屏障来确保其他线程将看到修改后的“就绪”值。 “就绪”是原子的只确保内存访问是有序的,以便在原子访问之前发生的修改实际上被刷新到主内存。这并不能保证其他线程会看到该内存,因为这些线程可能有自己的内存缓存。因此,要确保其他线程看到“就绪”修改,就需要互斥量。

{
std::unique_lock<std::mutex> lock(mtx);
ready = true;
}

关于等待条件下的C++线程死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38636704/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com