monkeyking
monkeyking

Reputation: 6948

make main program wait for threads to finish

In the following code I create some number of threads, and each threads sleeps for some seconds.

However my main program doesn't wait for the threads to finish, I was under the assumption that threads would continue to run until they finished by themselves.

Is there someway of making threads continue to run even though the calling thread finishes.

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

Thanks

Edit:

Sorry for not clarifying, is it possible without explicitly keeping track of my current running threads and by using join.

Upvotes: 12

Views: 22748

Answers (4)

Duck
Duck

Reputation: 27542

You learned your assumption was wrong. Main is special. Exiting main will kill your threads. So there are two options:

  1. Use pthread_exit to exit main. This function will allow you to exit main but keep other threads running.

  2. Do something to keep main alive. This can be anything from a loop (stupid and inefficient) to any blocking call. pthread_join is common since it will block but also give you the return status of the threads, if you are interested, and clean up the dead thread resources. But for the purposes of keeping main from terminating any blocking call will do e.g. select, read a pipe, block on a semaphore, etc.

Since Martin showed join(), here's 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);
}

Upvotes: 3

Loki Astari
Loki Astari

Reputation: 264361

You need to join each thread you create:

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

Upvotes: 3

Vinicius Kamakura
Vinicius Kamakura

Reputation: 7778

You need to keep track of the threads. You are not doing that because you are using the same thread1 variable to every thread you are creating.

You track threads by creating a list (or array) of pthread_t types that you pass to the pthread_create() function. Then you pthread_join() those threads in the list.

edit:

Well, it's really lazy of you to not keep track of running threads. But, you can accomplish what you want by having a global var (protected by a mutex) that gets incremented just before a thread finishes. Then in you main thread you can check if that var gets to the value you want. Say nThreads in your sample code.

Upvotes: 3

Armen Tsirunyan
Armen Tsirunyan

Reputation: 132984

Each program has a main thread. It is the thread in which your main() function executes. When the execution of that thread finishes, the program finishes along with all its threads. If you want your main thread to wait for other threads, use must use pthread_join function

Upvotes: 4

Related Questions