c - 理解线程

标签 c linux multithreading pthreads

我在 高级 Linux 编程 中遇到了一个概念。这是 a link :引用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 会导致相同的进程 ID。但是,书上的结果不一样。

请告诉我他在说什么..?书上/我的答案错了吗?

最佳答案

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

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

我尝试使用包含来自 ubuntu libc6 (2)

的 libc 的 linux 运行该程序
$ ./test
main thread pid is 2609
child thread pid is 2609

libc(1)使用linuxthreads实现pthread

而 libc (2) 使用 NPTL(“Native posix thread library”)实现 pthread

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

each thread is really a distinct process with a distinct PID, and signals sent to the PID of a thread can only be handled by that thread

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

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

NPTL 是由 redhat 团队开发的。并根据 redhat NPTL document : NPTL 实现中解决的问题之一是:

(Chapter: Problems with the Existing Implementation, page5)

Each thread having a different process ID causes compatibility problems with other POSIX thread implementations. This is in part a moot point since signals can'tbe used very well but is still noticeable


这就解释了您的问题。

您正在使用包含 pthread 的 NPTL(“ native posix 线程库”)实现的新 libc 版本

本书使用旧版本的 libc,其中包含 pthread 的 linuxthreads 实现

关于c - 理解线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19676071/

相关文章:

c - 二指针法

android - 如何在 android 中重新构建 HAL?

c - gcc前增量和后增量优化

java - 如何更改我的 Thread 实现以使用 ExecutorService

c# - 当子线程执行某个操作时通知父线程 [C#]

java - Java中如何实现多个线程下载单表数据?

c - scanf在c中的数学表达式

C:将 uint8 数组转换为包含其字节的十六进制表示形式的字符串

c++ - 尝试使用 CreateFileMapping 和自定义 DACL 创建只读共享内存区域在 OpenFileMapping 中失败

Linux 上的 R 包安装