我遇到了“ 高级Linux编程”中的 一个概念。这里是一个链接:请参阅 4.5 GNU / Linux线程实现 。
我对作者所说的概念很清楚,但是我对他解释的为线程打印processID的程序感到困惑。
这是代码
#include <pthread.h> #include <stdio.h> #include <unistd.h> void* thread_function (void* arg) { fprintf (stderr, "child thread pid is %d\n", (int) getpid ()); /* Spin forever. */ while (1); return NULL; } int main () { pthread_t thread; fprintf (stderr, "main thread pid is %d\n", (int) getpid ()); pthread_create (&thread, NULL, &thread_function, NULL); /* Spin forever. */ while (1); return 0; }
根据作者,上述代码的输出为
% cc thread-pid.c -o thread-pid -lpthread % ./thread-pid & [1] 14608 main thread pid is 14608 child thread pid is 14610
我编译时得到的输出是
[1] 3106 main thread pid is 3106 child thread pid is 3106
我知道,创建线程时,Linux内部调用 clone (大多数情况下),就像 fork 系统调用创建进程一样。唯一的区别是在进程中创建的线程共享相同的进程地址空间,而由父进程创建的进程将复制父进程地址空间。因此,我认为在线程中打印进程ID会导致相同的processID。但是,它在书中的结果并不相同。
请告诉我他在说什么..?本书/我的答案是否正确?
我在包含libc libuClibc-0.9.30.1.so (1)的 linux上获得了与本书相同的结果。
libuClibc-0.9.30.1.so
root@OpenWrt:~# ./test main thread pid is 1151 child thread pid is 1153
我试图用包含来自ubuntu的libc的linux运行该程序libc6 (2)
libc6
$ ./test main thread pid is 2609 child thread pid is 2609
libc (1) 使用linuxthreadspthread的实现
linuxthreads
和libc (2) 使用NPTL(“本地posix线程库”)执行pthread
NPTL
根据linuxthreads FAQ(在J.3中回答):
每个线程实际上都是具有不同PID的不同进程,并且发送到线程PID的信号只能由该线程处理
因此,在使用linuxthreads实现的旧libc中,每个线程都有其不同的PID
在使用NPTL实现的新libc版本中,所有线程都具有与主进程相同的PID。
该NPTL是由红帽团队开发。并且根据redhat NPTL文档:在NPTL实现中解决的问题之一是:
(第5章:现有实施中的问题) 每个具有不同进程ID的线程都会导致与其他POSIX线程实现的兼容性问题。这部分是有争议的,因为信号不能很好地使用,但仍然很明显
(第5章:现有实施中的问题)
每个具有不同进程ID的线程都会导致与其他POSIX线程实现的兼容性问题。这部分是有争议的,因为信号不能很好地使用,但仍然很明显
这可以解释您的问题。
您正在使用新的libc版本,其中包含NPTLpthread 的(“ Native posix线程库”)实现
本书使用的旧版libc包含linuxthreadspthread的实现