Подтвердить что ты не робот

Нити в векторе не могут быть соединены

Я хочу сохранить коллекцию потоков в векторе и присоединить их ко всем перед выходом из моей программы. Я получаю следующую ошибку при попытке присоединиться к первому потоку независимо от того, сколько я размещаю в коллекции:

system_error: thread::join failed: No such process

Вот простой код, демонстрирующий мою проблему:

#include <thread>
#include <iostream>
#include <vector>
#include <functional>

using std::cout;
using std::endl;
using std::vector;
using std::thread;
using std::mem_fn;

int main()
{
  vector<thread> threads(1);
  threads.push_back(thread([]{ cout << "Hello" << endl; }));
  for_each(threads.begin(), threads.end(), mem_fn(&thread::join));

  // also tried --> for(thread &t : threads) t.join()
}

И я создаю его, используя следующие (проверенные clang++ 4.2.1 и g++ 5.3.1):

g++ -o src/thread_test.o -c -std=c++14 src/thread_test.cpp -pthread
g++ -o thread_test src/thread_test.o -pthread

Я вижу множество примеров, которые делают это только через Интернет. Что-то изменилось в контракте <thread> или <vector>, что сделало эти примеры несуществующими?

ПРИМЕЧАНИЕ. В качестве сторонних для будущих читателей я закончил добавление аргумента конструктора (1) после попытки присваивания {}, который завершился неудачно из-за частного конструктора копирования. В попытке избежать конструктора копирования я в конечном итоге выделил неинициализированные потоки - неосторожную ошибку.

4b9b3361

Ответ 1

vector<thread> threads(1);

Создает поток, доступ к которому можно получить по индексу 0.

threads.push_back(thread([]{ cout << "Hello" << endl; }));

Это добавляет второй поток, к которому можно получить доступ по индексу 1.

for_each(threads.begin(), threads.end(), mem_fn(&thread::join));

Это вызовет join для обоих объектов thread. Однако первый из них никогда не запускался, поэтому он не соединяется.

Вместо этого вы можете заменить vector<thread> threads(1); на vector<thread> threads; threads.reserve(1); и продолжать использовать push_back.