2012-01-05 2 views
4

я просто испытанного что-то вроде этого:Сообщений в цикле

boost::thread workerThread1(boost::bind(&Class::Function, this, ...); 
boost::thread workerThread2(boost::bind(&Class::Function, this, ...); 

и она отлично работает. Теперь я хочу, чтобы создать столько потоков, сколько у меня есть объектов в списке. У меня есть эксперимент с boost :: foreach, и это отлично работает. Но у меня проблемы с именами потоков.

Так упростил код выглядит следующим образом:

for 
{ 
    boost:thread name(...); 
} 

но, конечно, название не может быть здесь в цикле, потому что он переписывает себя и разве доступен после цикла. Как создать потоки, чтобы я мог присоединиться к ним, ведь все они были созданы?

ответ

3

Можете ли вы не просто создать список (или похожих) потоков, а затем просто создать их и добавить в список.

-то вроде следующего (который, вероятно, более псевдокод что-нибудь :-))

list<boost::thread*> threads; 

for 
{ 
    boost::thread* name = new boost::thread(...); 
    threads.push_back(name); 
} 

Как уже упоминалось в другом ответе вы можете использовать смарт-указатели, которые были бы лучше, и вы упомянули, у вас есть определенное количество потоков таким образом массив/вектор был бы лучшим выбором, но, как я сказал выше код не является совершенным в любом случае

+0

Хороший пример, но не должно быть thread.add (name) ;? – Patrick87

+0

@ Patrick87 Хороший улов. Я полагаю, что это не идеальный код, это не очень хорошее оправдание :-) – Firedragon

+0

Вы должны использовать интеллектуальные указатели, чтобы избежать утечек памяти. –

2

Почему бы не поместить потоки в свой собственный контейнер, например, вектор (по умному указателю при условии, что они не копируются)?

0

Отказ от ответственности: я не использую boost, но если он работает, как и остальные C++, я считаю, что это может быть по правильной линии. Удалит, если это мусор.

boost::thread** threads; 
threads = new boost::thread*[THREAD_COUNT]; 

for(int i = 0; i < THREAD_COUNT; i++) 
{ 
    threads[i] = new boost::thread(...); 
} 

... 

for(int i = 0; i < THREAD_COUNT; i++) 
    delete threads[i]; 

delete[] threads; 

...

Идея просто динамически выделять массив указателей на ваш тип объекта, на основе того, сколько вы хотите. Затем, для каждого из них, динамически создайте один и вызовите соответствующий конструктор в цикле. В конце концов вам понадобится очистить их, чтобы вы могли использовать вызовы delete []. Я не понимаю, почему malloc()/free() и/или типы векторов тоже не будут работать.

+1

Вы должны использовать интеллектуальные указатели; здесь возникает утечка памяти, если создание потока не выполняется. –

+0

'malloc' /' free' не будет работать, потому что они не создают и не уничтожают объект 'thread'; они выделяют необработанную память, поэтому они почти никогда не используются в C++. 'vector' должен работать в C++ 11, но не C++ 03, где требуется, чтобы тип объекта был доступен для копирования и назначения. –

3

Вы можете сохранить их в массиве:

size_t const thread_count = 5; 
boost::thread threads[thread_count]; 
for (size_t i = 0; i < thread_count; ++i) { 
    threads[i] = boost::bind(&Class::Function, this, ...)); 
} 

В C++ 11, вы можете держать std::thread в дружелюбнее контейнерах, такие как std::vector:

std::vector<std::thread> threads; 
for (int i = 0; i < 5; ++i) { 
    threads.push_back(std::thread(boost::bind(&Class::Function, this, ...)))); 
} 

Это не будет работать с boost::thread в C++ 03, так как boost::thread не копируемый; назначение из временного в моем примере работает из-за некоторой магии Boost, которая сортирует эмулирует семантику перемещения. Я также не мог заставить его работать с boost::thread в C++ 11, но это может быть потому, что у меня нет последней версии Boost. Поэтому в C++ 03 вы застряли либо с массивом, либо с контейнером (желательно умных) указателей.

12

Почему бы вам не использовать boost::thread_group? Вы можете создавать/добавлять/удалять темы и присоединяться к ним (boost::thread_group::join_all()).

boost::thread_group tgroup; 
for(...) 
{ 
    tgroup.create_thread(boost::bind(&Class::Function, this, ...)) ; 
} 
tgroup.join_all(); 

Но будьте осторожны относительно числа потоков, вы создаете, слишком много нитей могут привести к OutOfMemory.

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