2016-06-30 2 views
18

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

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

И я строить его с помощью следующего (пробовал лязг ++ 4.2.1 и г ++ 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) после попытки присвоения {}, которое не выполняется из-за частного конструктора копирования. Пытаясь избежать конструктора копирования, я в конечном итоге выделил неинициализированные потоки - неосторожную ошибку.

+1

Используйте флагов компилятора '-pthread' как для скомпилирования, так и для компоновки, а не для связывания' -lpthread'. –

+0

Я использую scons, поэтому он форматирует мои аргументы библиотеки для меня. На самом деле он работает без -pthread или -lpthread, и я добавил его только для того, чтобы убедиться, что во время моих проблем я не заметил некоторых деталей реализации. Итак, 1) я думаю, что компилятор добавляет эти флаги для меня молча, и 2) почему предпочтительнее нестандартная lib? –

+3

'-lpthread' - это прямой запрос к компоновщику, тогда как' -pthread' - это опция, интерпретируемая драйвером компилятора. Если вы используете '-pthread' последовательно и для компиляции, и для времени ссылки, это дает драйверу компилятора возможность сделать что-либо _else_, которое может потребоваться, помимо связывания в libpthread, для создания многопоточной программы. Тем не менее, я не споткнулся о системе, в которой за многие годы на самом деле нужно было что-то еще. – zwol

ответ

33

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.

Смежные вопросы