了解Pthreads

Raj*_*nde 9 c linux multithreading pthreads

我在高级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;
} 
Run Code Online (Sandbox Code Playgroud)

根据作者的上述代码的输出是

% cc thread-pid.c -o thread-pid -lpthread
% ./thread-pid &
[1] 14608
main thread pid is 14608
child thread pid is 14610 
Run Code Online (Sandbox Code Playgroud)

我编译时得到的输出是

[1] 3106
main thread pid is 3106
child thread pid is 3106
Run Code Online (Sandbox Code Playgroud)

据我所知,要创建一个线程,linux内部调用clone(大多数情况下),与fork系统调用一样,创建一个进程.唯一的区别是在进程中创建的线程共享相同的进程地址空间,而由父进程创建的进程复制父进程地址空间.所以,我认为在线程中打印进程ID会产生相同的processID.但是,它在书中的结果并不相同.

请告诉他他在说什么..?这本书/我的答案是错误的吗?

MOH*_*MED 9

我得到了包含libc libuClibc-0.9.30.1.so (1)的 linux的相同结果.

root@OpenWrt:~# ./test
main thread pid is 1151
child thread pid is 1153
Run Code Online (Sandbox Code Playgroud)

我尝试用包含ubuntu的libc的linux运行这个程序libc6 (2)

$ ./test
main thread pid is 2609
child thread pid is 2609
Run Code Online (Sandbox Code Playgroud)

libc (1)使用linuxthreadspthread的实现

并且libc (2)使用NPTL("原生posix线程库")pthread的实现

根据linuxthreads常见问题解答(在J.3回答中):

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

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

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

NPTL是由redhat团队开发的.并根据redhat NPTL文件:NPTL实施中解决的问题之一是:

(章节:现有实施的问题,第5页)

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


这解释了你的问题.

您正在使用包含NPTLpthread("Native posix线程库")实现的新libc版本

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


Mic*_*urr 7

你工作的文字非常古老(2001年).较旧版本的Linux将线程实现为具有共享地址空间的独立进程.每个线程都有一个单独的pid.但是,此线程模型不符合POSIX,并且存在许多可移植性问题.

从2.6左右开始,Linux切换到"Native POSIX Thread Library"(NPTL).在此实现中,线程不会获得自己的PID.