заставить основную программу ждать завершения потоков - PullRequest
11 голосов
/ 24 июня 2011

В следующем коде я создаю некоторое количество потоков, и каждый поток спит несколько секунд.

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

Есть ли способ заставить потоки продолжать работать, даже если вызывающий поток завершает свою работу.

#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;
}

Спасибо

Редактировать:

Извините, что не уточнил, возможно ли это без явного отслеживания моих текущих запущенных потоков и с помощью объединения.

Ответы [ 4 ]

3 голосов
/ 24 июня 2011

Каждая программа имеет основной поток. Это поток, в котором выполняется ваша функция main (). Когда выполнение этого потока заканчивается, программа завершается вместе со всеми своими потоками. Если вы хотите, чтобы ваш основной поток ожидал других потоков, используйте команду pthread_join function

2 голосов
/ 24 июня 2011

Вам необходимо присоединиться к каждой создаваемой вами теме:

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);
    }
}
2 голосов
/ 24 июня 2011

Вам необходимо следить за темами. Вы этого не делаете, потому что вы используете одну и ту же переменную thread1 для каждого создаваемого вами потока.

Вы отслеживаете потоки, создавая список (или массив) типов pthread_t, которые вы передаете в функцию pthread_create(). Затем вы pthread_join() эти темы в списке.

редактирование:

Что ж, вам действительно лень не следить за запущенными потоками. Но вы можете достичь того, что вы хотите, имея глобальную переменную (защищенную мьютексом), которая увеличивается на единицу непосредственно перед завершением потока. Затем в главном потоке вы можете проверить, достигает ли эта переменная желаемого значения. Скажите nThreads в вашем примере кода.

1 голос
/ 24 июня 2011

Вы узнали, что ваше предположение было неверным.Главное особенное.Выход из main убьет ваши темы.Таким образом, есть два варианта:

  1. Используйте pthread_exit для выхода из основного.Эта функция позволит вам выйти из основного режима, но при этом другие потоки будут работать.

  2. Сделайте что-нибудь, чтобы поддержать основной.Это может быть что угодно от цикла (глупого и неэффективного) до любого блокирующего вызова.pthread_join встречается часто, так как он блокирует, но также дает вам статус возврата потоков, если вам это интересно, и очищает ресурсы мертвых потоков.Но для того, чтобы не допустить завершения функции main, любой блокирующий вызов будет делать, например, select, читать канал, блокировать семафор и т. Д.*:

    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);
    }
    
...