Примером решения может быть:
std::vector<std::thread> my_threads{};
my_threads.reserve(20);
for(int i = 0; i < 20; i++)
my_threads.emplace_back([i]{
std::cout << "[" << i << "] Going to sleep\n";
this_thread::sleep_for(std::chrono::seconds{1});
std::cout << "[" << i << "] Hey I'm back :)\n";
});
for(auto& thread : my_threads)
if(thread.joinable())
thread.join();
Обратите внимание на последние строки дерева. Если вы не присоединитесь или не отсоедините свои потоки, вы получите прерывание.
Это предотвращает утечку неуправляемых потоков в ваше приложение.