使用std :: map和std :: thread的意外行为

时间:2017-04-11 20:20:08

标签: c++ multithreading c++11 stl

所以我的应用程序需要一个线程池,这导致我创建了一个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()

之后,调用terminate并且程序接收SIGABRT信号。

实时调试表明正在调用joinable(),因为join()是真的,但我只是检查并认为它不是!

此外,克服它的方法只是在threads.erase(1); 之后添加以下行:

std::thread

这让我有点困惑,因为看起来insert的新实例是在我的[0, someint]电话之前创建的......有人可以暗示我这个意想不到的行为吗?

1 个答案:

答案 0 :(得分:4)

来自http://en.cppreference.com/w/cpp/container/map/insert

  

如果容器尚未包含具有等效键的元素,则将元素插入容器中。

您的地图已在密钥1中包含元素,因此第二个threads.insert不会执行任何操作。您只是尝试在同一std::thread上加入两次。这就是threads.erase(1);解决问题的原因,您的地图不再包含密钥1的主题。