1

So I need a thread pool for my application, which led me to create a std::map<int, std::thread> object. I've encountered some very unexpected behavior, which can be simplified to this:

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();

The output is

I'm the first thread and I'm gonna work
Thread 1 joinable? 0

Right after, std::terminate() is called and program receives SIGABRT signal.

Live debugging suggested that terminate is being called because joinable() is true, but I just checked and figured it's not!

Moreover, the way to overcome it was simply to add the following line after join()ing:

threads.erase(1);

That leaves me a bit confused, as it looks like a new instance of std::thread was created just before my insert call... Can someone hint me about this unexpected behavior?

Omer Perry
  • 108
  • 5

1 Answers1

4

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

Inserts element(s) into the container, if the container doesn't already contain an element with an equivalent key.

Your map already contains an element at key 1 so the second threads.insert doesn't do anything. You are simply trying to join twice on the same std::thread. This is why threads.erase(1); solves the problem, your map no longer contains a thread at key 1.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87
  • Great, thank you. So there is no straightforward API for overriding an existing key, am I right? – Omer Perry Apr 11 '17 at 20:39
  • @OmerPerry `treads[1] = std::thread( [](){ /* do work*/ } );` will "overwrite" the thread at key `1` with a new one. There is no method for deleting then replacing an element in a single call, however move assignment should do the same thing for any movable type. – François Andrieux Apr 11 '17 at 20:40