【发布时间】:2023-03-14 06:32:02
【问题描述】:
我想使用 /proc/[pid]/task/. 枚举特定进程的线程。但是在 proc 手册页中,它说:
在多线程进程中,如果主线程已经终止(通常通过调用 pthread_exit(3)),则 /proc/[pid]/task 目录的内容不可用。
然后我写一些代码,
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
void* PrintHello(void* data){
pthread_t tid = (pthread_t)data;
int rc;
rc = pthread_join(tid, NULL);
if(rc){
exit(1);
} else{
printf("Hello from new thread %d - got %d\n", pthread_self(), data);
sleep(180);
pthread_exit(NULL);
}
}
int main(int argc, char* argv[]){
int rc;
pthread_t thread_id;
thread_t tid;
tid = pthread_self();
printf("\nmain thread(%d) ", tid);
rc = pthread_create(&thread_id, NULL, PrintHello, (void*)tid);
if(rc){
printf("\n ERROR: return code from pthread_create is %d \n", rc);
exit(1);
}
sleep(1);
printf("\n Created new thread (%d) ... \n", thread_id);
pthread_exit(NULL);
}
主线程调用pthread_exit()后,变成僵尸。 /proc/[pid]/task 目录仍然存在,但 /proc/[pid]/maps 为空。
$ ./a.out &
main thread(164759360)
Created new thread (164755200) ...
Hello from new thread 164755200 - got 164759360
$ ps auwx | grep a.out
spyder 5408 0.0 0.0 0 0 pts/0 Zl+ 10:27 0:00 [a.out] <defunct>
spyder 5412 0.0 0.0 109400 896 pts/1 S+ 10:27 0:00 grep --color=auto a.out
$ ls /proc/5408/task/
5408 5409
$ cat /proc/5408/maps
$ cat /proc/5408/status
Name: a.out
State: Z (zombie)
Tgid: 5408
Pid: 5408
....
$ cat /proc/5409/maps
00400000-00401000 r-xp 00000000 fd:02 2752690 /home/spyder/a.out
00600000-00601000 rw-p 00000000 fd:02 2752690 /home/spyder/a.out
018cb000-018ec000 rw-p 00000000 00:00 0 [heap]
3dcf000000-3dcf020000 r-xp 00000000 fd:01 139203 /usr/lib64/ld-2.15.so
3dcf21f000-3dcf220000 r--p 0001f000 fd:01 139203 /usr/lib64/ld-2.15.so
....
有什么问题吗?
【问题讨论】:
-
我认为文档已经过时了。理想情况下,
task和maps仍然可用,但认为自己很幸运,至少存在task。并且不要依赖于在旧内核上工作,因为它可能不会...... -
你的主进程先退出,然后你的子进程退出。但是主进程退出会导致他所有的子进程退出。这是一个冲突。
-
@MYMNeo 我不认为你明白这一点。首先它是主线程而不是主进程,我只使用 pthread_exit 退出主线程,其他线程按预期继续。我的问题是为什么主线程会变成僵尸。