简体   繁体   English

当主线程退出时,其他线程是否也退出?

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

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?当 main 函数返回时,其他线程是否也退出? 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?打印出来,线程 test1 和 test2 也退出了,谁能告诉我为什么?

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.您应该在每个新线程上使用pthread_join()来通知调用线程等待子线程,暂停执行 - 并进程退出 - 直到这些线程终止。

Calling pthread_detach on the created threads won't keep them around after a process exits.在进程退出后,在创建的线程上调用pthread_detach不会保留它们。 From the linux man page :从 linux 手册页

The detached attribute merely determines the behavior of the system when the thread terminates; detached 属性仅仅决定了线程终止时系统的行为; it does not prevent the thread from being terminated if the process terminates using exit(3) (or equivalently, if the main thread returns).如果进程使用 exit(3) 终止(或等效地,如果主线程返回),它不会阻止线程被终止。

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.您有时会看到在main使用pthread_exit而不是显式pthread_join调用,目的是通过这种方式退出main将允许其他线程继续运行。 In fact, the linux man page states this explicitly:事实上, linux 手册页明确说明了这一点:

To allow other threads to continue execution, the main thread should terminate by calling pthread_exit() rather than exit(3).为了允许其他线程继续执行,主线程应该通过调用 pthread_exit() 而不是 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

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. pthread_join需要目标线程的pthread_t ,因此您的代码需要稍作更改,因为您需要在调用pthread_join之前创建两个线程以等待它们。 So you can't call it in startThread .所以你不能在startThread调用它。 You'll need to return a pthread_t , or pass a pointer to a pthread_t to your startThread function.您需要返回pthread_t ,或将指向pthread_t的指针传递给startThread函数。

When the main thread returns (ie, you return from the main function), it terminates the entire process.当主线程返回时(即从main函数返回),它终止整个进程。 This includes all other threads.这包括所有其他线程。 The same thing happens when you call exit .调用exit时也会发生同样的事情。 You can avoid this by calling pthread_exit .您可以通过调用pthread_exit来避免这种情况。

The purpose of pthread_detach is to make it so you don't need to join with other threads in order to release their resources. pthread_detach的目的是让你不需要加入其他线程来释放它们的资源。 Detaching a thread does not make it exist past process termination, it will still be destroyed along with all the other threads.分离一个线程并不会让它在进程终止后存在,它仍然会与所有其他线程一起被销毁。

All the threads in your process will be terminated when you return from main() .当您从main()返回时,您进程中的所有线程都将终止。

The libc library is the one responsible for implementing this behavior by calling exit() when the main() function returns. libc库负责通过在main()函数返回时调用exit()来实现这一行为。 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.反过来, exit()函数将最终调用一个名为_exit()的瘦包装器函数,该函数(从libc v2.3 开始)将最终调用exit_group系统调用并结束您的进程并终止其所有线程。

This last system call is the one responsible for the behavior you noticed.最后一个系统调用负责您注意到的行为。

We can see this subtle note in the _exit() manual here :我们可以在看到这种微妙的音符_exit()手册这里

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.如果您打算避免这种行为,唯一的选择是调用pthread_exit ,这将结束您的主线程并阻止您返回到libc__libc_start_main()函数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM