When the main thread exits, do other threads also exit?

laifjei picture laifjei · Aug 9, 2012 · Viewed 31.1k times · Source

I have a problem about main threads and other threads in the same process. When the main function returns, do the other threads exit too? I am confused about this.

Consider the following test code:

void* test1(void *arg)
{
    unsigned int i = 0;
    while (1){
        i+=1;
    }
    return NULL;
}

void* test2(void *arg)
{
    long double i = 1.0;
    while (1){
        i *= 1.1;
    }
    return NULL;
}

void startThread ( void * (*run)(void*), void *arg) {
  pthread_t t;
  pthread_attr_t attr;
  if (pthread_attr_init(&attr) != 0
      || pthread_create(&t, &attr, run, arg) != 0
      || pthread_attr_destroy(&attr) != 0
      || pthread_detach(t) != 0) {
    printf("Unable to launch a thread\n");
    exit(1);
  }
}

int main()
{
    startThread(test1, NULL);
    startThread(test2, NULL);

    sleep(4);
    printf("main thread return.\n");

    return 0;
}

When the "main thread return." prints out, thread test1 and test2 also exit, can anyone tell me why?

Answer

pb2q picture pb2q · Aug 9, 2012

You should use pthread_join() on each of the new threads, to inform the calling thread to wait on the sub-threads, suspending execution - and process exit - until those threads terminate.

Calling pthread_detach on the created threads won't keep them around after a process exits. From the linux man page:

The detached attribute merely determines the behavior of the system when the thread terminates; it does not prevent the thread from being terminated if the process terminates using exit(3) (or equivalently, if the main thread returns).

You'll sometimes see a pthread_exit in main used instead of explicit pthread_join calls, the intent being that exiting main in this way will allow other threads to continue running. In fact, the linux man page states this explicitly:

To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).

But I don't know if this is expected behavior on all platforms, and I've always stuck to using pthread_join.

pthread_join requires the pthread_t for the target thread, so your code will need to change a bit since you need to create both threads before calling pthread_join to wait for them both. So you can't call it in startThread. You'll need to return a pthread_t, or pass a pointer to a pthread_t to your startThread function.