【发布时间】:2017-09-07 09:43:22
【问题描述】:
所以我的应用程序需要一个线程池,这导致我创建了一个std::map<int, std::thread> 对象。
我遇到了一些非常意外的行为,可以简化为:
std::map<int, std::thread> threads;
threads.insert(std::pair<int, std::thread>(1, std::thread([]() {
std::cout << "I'm the first thread and I'm gonna work\n";
})));
threads[1].join();
std::cout << "Thread 1 joinable? " << threads[1].joinable() << "\n";
threads.insert(std::pair<int, std::thread>(1, std::thread([]() {
std::cout << "I'm not gonna work at all\n";
})));
threads[1].join();
输出是
I'm the first thread and I'm gonna work
Thread 1 joinable? 0
紧接着,std::terminate() 被调用并且程序接收到 SIGABRT 信号。
实时调试提示 terminate 被调用,因为 joinable() 是真的,但我刚刚检查并发现它不是!
此外,克服它的方法只是在join()ing 之后添加以下行:
threads.erase(1);
这让我有点困惑,因为看起来std::thread 的新实例是在我调用insert 之前创建的...有人可以提示我这种意外行为吗?
【问题讨论】:
-
在 stdout 上跟踪时,不要忘记刷新。
-
@molbdnilo - 换行应该这样做。
-
@OliverCharlesworth
'\n'不会刷新std::cout。 -
@FrançoisAndrieux - 这对我来说是个新闻:/(至少在 cout 在典型环境中包装标准输出的世界中。)你能澄清一下吗?
-
@OliverCharlesworth:
\n如果直接连接到终端,std::cout会刷新,否则不会。 stackoverflow.com/q/796865/845092
标签: c++ multithreading c++11 stl