为什么可加入的线程在pthread_join之前终止?

Why does a joinable thread terminate before pthread_join?

提问人:helhel 提问时间:9/24/2023 最后编辑:Toby Speighthelhel 更新时间:9/25/2023 访问量:33

问:

pthread_join函数的文档说:

未能与可联接的线程(即 Not Detached),产生一个“僵尸线程”。

据我了解,在线程终止后,它仍然是一个僵尸,直到我们调用pthred_join。但是,我编写了一个程序,结果发现已完成的可加入线程在返回后完全终止。但是我们如何在pthread_join中获取线程退出代码呢?退出代码存储在哪里?

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>

void *mythread(void *arg)
{
    printf("mythread [%d %d %d]: Hello from mythread!\n", getpid(), getppid(), gettid());
    int *result = malloc(sizeof(int));
     *result = 42;
     return result;
}

int main() {
    pthread_t tid;
    int err;

    printf("main [%d %d %d]: Hello from main!\n", getpid(), getppid(), gettid());

    err = pthread_create(&tid, NULL, mythread, NULL);
    if (err) {
        printf("main: pthread_create() failed: %s\n", strerror(err));
        return -1;
    }

    sleep(1000);

    void *thread_result;

    if (pthread_join(tid, &thread_result) != 0) {
        perror("Thread join failed");
        return 1;
    }
    printf("Thread returned: %d\n", *((int *)thread_result));
    return 0;
}

启动程序

查看进程线程

可以看出,在工艺表中只有主线程。

C Linux pthreads POSIX

评论


答:

2赞 n. m. could be an AI 9/24/2023 #1

仍未加入的可加入线程的线程退出代码存储在僵尸线程中。这或多或少就是僵尸线程:存储线程退出代码的数据片段。

在 Linux 下,僵尸线程不是一个进程(即在进程表中没有条目),因此不会显示它。 调用(系统调用,而不是同名的 C 库函数),以便与该线程对应的进程真正终止。在工艺表中没有它的踪迹。然而,仍然有一条僵尸线挂在某处。pspthread_exitexit

评论

0赞 helhel 9/24/2023
有趣的是,如果主线程先调用pthread_exit,它仍然会进入僵尸状态。这是因为主线程必须将进程退出代码传递给父进程,还是为什么?
0赞 n. m. could be an AI 9/24/2023
@helhel,如果主线程调用pthread_exit,则该进程将变成僵尸,直到所有其他线程退出。它与僵尸线程的状态不同。
0赞 John Bollinger 9/25/2023
@helhel,在进程的所有线程终止之前,您不会得到通常所说的“僵尸进程”。如果进程的初始线程在进程中还有其他活动线程时通过调用终止,则该线程将成为僵尸线程。它可以通过任何剩余的线程正常连接。在这种情况下(一如既往),任何活动线程都可以终止整个进程,并通过调用 .如果它们都在没有调用的情况下终止,则就好像执行达到了 的关闭:退出状态为 0。pthread_exit()exit()exit()}main()