【发布时间】:2019-08-01 00:23:08
【问题描述】:
我正在尝试了解如何更好地使用条件变量,并且我有以下代码。
行为。
代码的预期行为是:
- 每个线程打印“线程n等待”
- 程序一直等到用户按下回车键
- 当用户按下回车键时,notify_one 会为每个线程调用一次
- 所有线程都打印“thread n ready.”,然后退出
代码的观察到的行为是:
- 每个线程打印“线程n等待”(预期)
- 程序一直等到用户按下回车键(预期)
- 当用户按下回车键时,每个线程都会调用一次 notify_one (预期)
- 其中一个线程打印“线程 n 就绪”,但随后代码挂起。 (???)
问题。
为什么代码会挂起?以及如何让多个线程等待同一个条件变量?
代码
#include <condition_variable>
#include <iostream>
#include <string>
#include <vector>
#include <thread>
int main() {
using namespace std::literals::string_literals;
auto m = std::mutex();
auto lock = std::unique_lock(m);
auto cv = std::condition_variable();
auto wait_then_print =[&](int id) {
return [&, id]() {
auto id_str = std::to_string(id);
std::cout << ("thread " + id_str + " waiting.\n");
cv.wait(lock);
// If I add this line in, the code gives me a system error:
// lock.unlock();
std::cout << ("thread " + id_str + " ready.\n");
};
};
auto threads = std::vector<std::thread>(16);
int counter = 0;
for(auto& t : threads)
t = std::thread(wait_then_print(counter++));
std::cout << "Press enter to continue.\n";
std::getchar();
for(int i = 0; i < counter; i++) {
cv.notify_one();
std::cout << "Notified one.\n";
}
for(auto& t : threads)
t.join();
}
输出
thread 1 waiting.
thread 0 waiting.
thread 2 waiting.
thread 3 waiting.
thread 4 waiting.
thread 5 waiting.
thread 6 waiting.
thread 7 waiting.
thread 8 waiting.
thread 9 waiting.
thread 11 waiting.
thread 10 waiting.
thread 12 waiting.
thread 13 waiting.
thread 14 waiting.
thread 15 waiting.
Press enter to continue.
Notified one.
Notified one.
thread 1 ready.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
Notified one.
【问题讨论】:
-
当您不持有锁时,您正在调用
cv.wait(lock)- 未定义的行为,但通常会先获取锁。由于您永远不会释放锁,因此只有第一个线程可以打印其消息,其余所有线程都在等待永远不会释放的锁......
标签: c++ multithreading condition-variable