是否已退出但可连接的线程不在 /proc/[pid]/task 下?

Posted

技术标签:

【中文标题】是否已退出但可连接的线程不在 /proc/[pid]/task 下?【英文标题】:Is exited but joinable threads not under /proc/[pid]/task? 【发布时间】:2017-11-06 15:23:27 【问题描述】:

据我所知,由 pthread_create 创建的具有 NULL 线程属性的线程将在线程退出后,如果其宿主进程仍处于活动状态,则线程可连接。所以,我写了一个演示来验证这一点:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
void* thread_function(void* argv)

    printf("thread_function invoked\n");
    return NULL;


int main(int argc, char* argv[])

    pthread_t tid;
    pthread_create(&tid, NULL, thread_function, NULL);
    pause();
    return 0;

编译:

gcc -o 01_detach 01_detach.c -pthread

然后运行:

./01_detach 调用线程函数

查找进程:

ps -aux | grep 01_detach 刘聪5856 0.0 0.0 14708 1032 pts/7 S+ 22:59 0:00 ./01_detach

找到可连接的线程:

ls /proc/5856/task 5856

我认为/proc/5856/task中应该有两个条目,一个用于主线程,另一个用于退出的可连接线程。这要怎么解释?退出的线程总是不在 /proc/[pid]/task 下吗?如何找出 Linux 中已退出但可连接的线程?

平台:

Linux liucong-vaio 4.4.0-98-generic #121~14.04.1-Ubuntu SMP Wed Oct 11 11:54:55 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

gcc 版本:

gcc 版本 4.8.5 (Ubuntu 4.8.5-2ubuntu1~14.04.1)

【问题讨论】:

尽管您打算使用这些信息来编写一些代码,但您的问题实际上是 Linux proc 文件系统,而不是编程。 抱歉,实在找不到合适的标题,提交之前已经改了很多次标题,你对瓷砖有什么想法? 【参考方案1】:

据我所知,由 pthread_create 创建的线程属性为 NULL 的线程将在线程退出后,如果其宿主进程仍处于活动状态,则线程可连接。

几乎是的:默认情况下,POSIX 线程是可连接的,除非它们被显式分离。

我认为 /proc/5856/task 中应该有两个条目,一个用于 main 线程和另一个用于退出的可连接线程。

你似乎在这里匆忙下结论。 The Linux manual page for /proc 说:

这是一个目录,其中包含进程中每个线程的一个子目录。

您假设对于/proc 目的,已终止但未加入的可加入线程仍算作“进程中的线程”。这似乎是合理的,但文档并没有给予太多支持。

如何 解释这个?退出的线程总是不在 /proc/[pid]/task 下吗?

您几乎已经回答了自己的问题:不,您的测试表明它们不是。这可能在内核文档的某个地方有所涉及,但在我在几次搜索中找到的任何文档中都没有明确说明。然而,我已经参考过的同一个手册页也有这样的说明:

在多线程进程中,如果主线程已经终止,则/proc/[pid]/task 目录的内容不可用。

请注意,主线程已终止并不意味着整个进程已终止。

如何 找出 Linux 中已退出但可连接的线程?

我不知道有任何通用机制可以提取该信息。当然 pthreads API 没有提供它——就 pthreads 而言,希望了解属于它的线程的进程本身会跟踪该信息。

但你所有的努力似乎都极其迂回。 如果您想证明使用默认线程属性启动的线程是可加入的,那么为什么不直接加入呢?

【讨论】:

如果一个deamon进程中存在很多可加入的线程,如果程序员忘记加入这些线程,这在一定程度上是一种资源泄漏,所以,我只想找出泄漏源,但我找不到列出这些可连接线程的方法。 很公平,@cong,但这与您在问题中提出的动机完全不同。无论如何,据我所知,内核并没有提供面向用户的界面来发现等待加入的终止线程。当然 Pthreads API 不包含这样的接口。

以上是关于是否已退出但可连接的线程不在 /proc/[pid]/task 下?的主要内容,如果未能解决你的问题,请参考以下文章

如何查看正在运行线程的CPU核心?

1.9 进程pid,运行耗时 运行退出状态

查找已连接的 Unix Domain Socket 的 PID

Linux下进程信息/proc/pid/status文件深入分析

依靠 /proc/[pid]/status 检查另一个进程的身份

命令不在 J2me 的单独线程中工作