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

Viewed 38904

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?

3 Answers

All the threads in your process will be terminated when you return from main().

The libc library is the one responsible for implementing this behavior by calling exit() when the main() function returns. In turn, the exit() function will end up calling a thin-wrapper function named _exit() which (starting from libc v2.3) will finally invoke the exit_group system call and end up your process and also terminate all its threads.

This last system call is the one responsible for the behavior you noticed.

We can see this subtle note in the _exit() manual here:

C library/kernel differences
       In glibc up to version 2.3, the _exit() wrapper function invoked
       the kernel system call of the same name.  Since glibc 2.3, the
       wrapper function invokes exit_group(2), in order to terminate all
       of the threads in a process.

If your intention is to avoid this behavior, the only option is to call pthread_exit which will end your main thread and prevent you from returning to the libc's __libc_start_main() function.

Related