gpt4 book ai didi

c++ - std::condition_variable::notify_one() 不唤醒等待线程

转载 作者:搜寻专家 更新时间:2023-10-31 02:07:54 24 4
gpt4 key购买 nike

我有如下代码:

#include <mutex>
#include <condition_variable>
#include <future>

std::mutex mtx;
std::condition_variable cv;
std::future<void> worker;

void worker_thread() {
{
std::lock_guard<std::mutex> lg{ mtx };
// do something 1
}
cv.notify_one();

// do something 2
}

int main() {
{
std::unique_lock<std::mutex> lg{ mtx };
worker = std::async(std::launch::async, worker_thread);
cv.wait(lg);
}
// do something 3
}

主线程没有继续执行 //do something 3 我不明白为什么。我认为 cv.notify_one() 行应该在 cv.wait(lg) 被主线程传递后从工作线程到达,所以没有理由挂起来。

工作线程负责一些流式数据处理,而主线程主要负责GUI事件处理。

//do something 1 是关于一些应该在工作线程内完成的初始化。主线程应该等待工作线程完成它。

//do something 2 是工作线程的主要工作。

//do something 3 是主线程的主要工作。

cv.notify_one() 更改为 cv.notify_all() 没有帮助。

条件变量的这种用法是否正确?

最佳答案

我不得不回到原来的答案,为此我向 Junekey 道歉。我误读了代码,并断定存在竞争条件。我无法重现该问题。我们需要一个实际上永远阻塞在 cv.wait 上的示例,以便弄清楚它为什么这样做。然而,如果没有其他原因,代码是不正确的,它可能会收到虚假通知并在 worker_thread 调用 cv.notify 之前通过 cv.wait。这种情况很少发生,但确实会发生。

此代码或多或少是规范的:

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

std::mutex mtx;
std::condition_variable cv;
bool worker_done = false; // <<< puts the "condition" in condition_variable

void worker_thread() {

// do something 1

{
std::lock_guard<std::mutex> lg{ mtx };
worker_done = true; // ... and whatever
}

cv.notify_one();

// do something 2
}

int main() {
std::thread workman(worker_thread);
{
std::unique_lock<std::mutex> lg{ mtx };
while (!worker_done) {
cv.wait(lg);
}
}
// do something 3
workman.join();
}

关于c++ - std::condition_variable::notify_one() 不唤醒等待线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48227174/

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