一尘不染

了解Pthread

linux

我遇到了“ 高级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。但是,它在书中的结果并不相同。

请告诉我他在说什么..?本书/我的答案是否正确?


阅读 249

收藏
2020-06-07

共1个答案

一尘不染

我在包含libc libuClibc-0.9.30.1.so (1)的 linux上获得了与本书相同的结果。

root@OpenWrt:~# ./test
main thread pid is 1151
child thread pid is 1153

我试图用包含来自ubuntu的libc的linux运行该程序libc6 (2)

$ ./test
main thread pid is 2609
child thread pid is 2609

libc (1) 使用linuxthreadspthread的实现

和libc (2) 使用NPTL(“本地posix线程库”)执行pthread

根据linuxthreads
FAQ
(在J.3中回答):

每个线程实际上都是具有不同PID的不同进程,并且发送到线程PID的信号只能由该线程处理

因此,在使用linuxthreads实现的旧libc中,每个线程都有其不同的PID

在使用NPTL实现的新libc版本中,所有线程都具有与主进程相同的PID。

NPTL是由红帽团队开发。并且根据redhat
NPTL文档
:在NPTL实现中解决的问题之一是:

(第5章:现有实施中的问题)

每个具有不同进程ID的线程都会导致与其他POSIX线程实现的兼容性问题。这部分是有争议的,因为信号不能很好地使用,但仍然很明显


这可以解释您的问题。

您正在使用新的libc版本,其中包含NPTLpthread 的(“ Native posix线程库”)实现

本书使用的旧版libc包含linuxthreadspthread的实现

2020-06-07