似乎condition_variable
notify_one
并不总是以应有的方式运作。
struct Task {
std::mutex mutex;
std::condition_variable cv;
std::atomic_bool launch{false};
};
void job(Task& task) {
std::unique_lock<std::mutex> lock{task.mutex};
task.cv.wait(lock, [&]{ return task.launch == true; });
}
int main() {
for (auto i=0 ; i<1000*1000 ; i++) {
Task task;
std::thread thread{job, std::ref(task)};
task.launch = true;
task.cv.notify_one();
thread.join();
}
}
这个程序几乎永远不会到达终点,绝大部分时间都会在循环中永久停止。 为什么会这样?
答案 0 :(得分:4)
这里有两个错误:
atomic_bool
只会造成开销。launch
标志的访问,则需要在写入之前锁定其互斥锁。您不是在main()
。说明:
main()
创建task
main()
创建thread
job()
锁定互斥锁job()
检查launch
,这是假的main()
设置launch
main()
发出无人接收的简历job()
由于第4步中launch
的值而等待简历通常,步骤3和6将是原子的,因为任何其他线程都不应该在不锁定互斥锁的情况下触及launch
。由于没有发生这种情况,允许进行相关操作的交错,最终导致意外行为。
答案 1 :(得分:1)
不清楚你想要什么,但是你的问题是,在线程有时间调用launch=true
之前主要实现notify_one()
和wait
的问题。在这种情况下,您应该知道notify
没有延迟,因此当join
上的广告被屏蔽时,您的主广告将被wait
屏蔽。