Заставить основную программу ждать завершения потоков
В следующем коде я создаю несколько потоков, и каждый поток засыпает в течение нескольких секунд.
Однако моя основная программа не дожидалась завершения потоков, я был в предположении, что потоки продолжат работать, пока они не закончат сами.
Есть ли способ сделать потоки продолженными, даже если вызывающий поток заканчивается.
#include <pthread.h>
#include <iostream>
#include <cstdio>
#include <cstdlib>
int sample(int min,int max){
int r=rand();
return (r %max+min );
}
void *worker(void *p){
long i = (long) p;
int s = sample(1,10);
fprintf(stdout,"\tid:%ld will sleep: %d \n",i,s);
sleep(s);
fprintf(stdout,"\tid:%ld done sleeping \n",i,s);
}
pthread_t thread1;
int main(){
int nThreads = sample(1,10);
for(int i=0;i<nThreads;i++){
fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads);
int iret1 = pthread_create( &thread1, NULL, worker, (void*) i);
pthread_detach(thread1);
}
// sleep(10);//work if this is not commented out.
return 0;
}
Спасибо
Edit:
Извините, что не уточнил, возможно ли это без явного отслеживания текущих текущих потоков и с помощью объединения.
Ответы
Ответ 1
Каждая программа имеет основной поток. Это поток, в котором выполняется ваша функция main(). Когда выполнение этого потока завершается, программа заканчивается вместе со всеми ее потоками. Если вы хотите, чтобы ваш основной поток ожидал других потоков, используйте pthread_join function
Ответ 2
Вам нужно следить за потоками. Вы не делаете этого, потому что используете одну и ту же переменную thread1
для каждого потока, который вы создаете.
Вы отслеживаете потоки, создавая список (или массив) типов pthread_t
, которые вы передаете функции pthread_create()
. Затем вы pthread_join()
те потоки в списке.
изменить:
Хорошо, вам на самом деле лениво не следить за запуском потоков. Но вы можете выполнить то, что хотите, имея глобальный var (защищенный мьютексом), который увеличивается до момента завершения потока. Затем в основной теме вы можете проверить, получает ли этот var значение, которое вы хотите. Скажите nThreads
в своем примере кода.
Ответ 3
Вам нужно присоединиться к каждой создаваемой теме:
int main()
{
int nThreads = sample(1,10);
std::vector<pthread_t> threads(nThreads);
for(i=0; i<nThreads; i++)
{
pthread_create( &threads[i], NULL, worker, (void*) i)
}
/* Wait on the other threads */
for(i=0; i<nThreads; i++)
{
status* status;
pthread_join(threads[i], &status);
}
}
Ответ 4
Вы поняли, что ваше предположение было неправильным. Главная особенность. Выход из главного будет убивать ваши потоки. Таким образом, есть два варианта:
-
Используйте pthread_exit
для выхода из основного. Эта функция позволит вам выйти из основного, но сохранить другие потоки.
-
Сделайте что-нибудь, чтобы сохранить живое. Это может быть любое из цикла (глупо и неэффективно) для любого блокирующего вызова. pthread_join
является обычным явлением, поскольку он блокирует, но также дает вам статус возврата потоков, если вы заинтересованы, и очищайте ресурсы мертвых потоков. Но в целях сохранения основной функции от завершения любого блокирующего вызова будет действовать, например. выбирать, читать канал, блокировать семафор и т.д.
Так как Мартин показал join()
, здесь pthread_exit()
:
int main(){
int nThreads = sample(1,10);
for(int i=0;i<nThreads;i++){
fprintf(stderr,"\t-> Creating: %d of %d\n",i,nThreads);
int iret1 = pthread_create( &thread1, NULL, worker, (void*) i);
pthread_detach(thread1);
}
pthread_exit(NULL);
}