APUE是否错误了解linux线程描述?

时间:2012-02-14 16:47:15

标签: c linux multithreading linux-kernel

在图11.2 APUE 2nd中,有一个用于线程API的代码演示用法,如下所示:

#include <pthread.h>
#include <stdio.h>

pthread_t ntid;

void printids(const char *s)
{
        pid_t pid;
        pthread_t tid;

        pid = getpid();
        tid = pthread_self();
        printf("%s pid %u tid %u (0x%x)\n", s,
                (unsigned int)pid, (unsigned int)tid, (unsigned int)(tid));
}

void *thr_fn(void *arg)
{
        printids("new thread: ");

        return (void*)0;
}

int main(void)
{
        int err;

        err = pthread_create(&ntid, NULL, thr_fn, NULL);
        if (err != 0)
                return -1;

        printids("main thread: ");
        sleep(1);
        return 0;
}

并且书中说输出是这样的,

$./a.out
new thread: pid 6628 ...
main thread: pid 6626 ...

Pid与众不同!这是因为“Linux使用clone()来实现线程,与fork()相同,因此系统将线程视为共享资源的独立进程”。

但是当我测试时,我发现结果与APUE结果不同,即

$ ./a.out 
main thread:  pid 13301 tid 3078153920 (0xb778e6c0)
new thread:  pid 13301 tid 3078151024 (0xb778db70)
pid是一样的! APUE过时了吗?但是linux确实使用clone来实现线程,而在linux内核中,它们被视为不同的进程。为什么进程ID是一样的?

1 个答案:

答案 0 :(得分:1)

你的版本APUE很可能会过时,因为它引用的是LinuxThreads而不是NPTL。

这是克隆(2)手册页中的相关部分,它阐述了这个问题:

线程组是Linux 2.4中添加的一项功能,用于支持共享单个PID的一组线程的POSIX线程概念。在内部,此共享PID是所谓的线程组标识符(TGID)线程组。从Linux 2.4开始,调用getpid(2)返回调用者的TGID。

组中的线程可以通过其(系统范围的)唯一线程ID(TID)进行区分。函数结果返回给clone()的调用者时,新线程的TID可用,并且线程可以使用gettid(2)获取自己的TID。