C++线程僵局在等待条件上 toming在我的之前的两个问题中扩展,将一个线程作为成员变量的类操作移动操作,并在lambda中传递给线程 我不明白为什么线程...

问题描述 投票:0回答:0

通知线不需要将锁定与等待线保持的锁在同一静音上;实际上,这样做是悲观的,因为通知线程将立即再次阻止,等待通知线程释放锁。 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 don't 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++ multithreading c++11 gcc4.8
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.