【问题标题】:Why does printing the pointer to structure of type pthread, gives us thread ID?为什么打印指向 pthread 类型结构的指针会给我们线程 ID?
【发布时间】:2026-01-29 19:10:01
【问题描述】:

pthread的结构如下。取自https://stuff.mit.edu/afs/sipb/project/pthreads/include/pthread.h

    struct pthread {
    struct machdep_pthread  machdep_data;
    enum pthread_state      state;
    pthread_attr_t          attr;

    /* Signal interface */
    sigset_t                sigmask;
    sigset_t                sigpending;

    /* Time until timeout */
    struct timespec         wakeup_time;

    /* Cleanup handlers Link List */
    struct pthread_cleanup  *cleanup;

    /* Join queue for waiting threads */
    struct pthread_queue    join_queue;

    /* Queue thread is waiting on, (mutexes, cond. etc.) */
    struct pthread_queue    *queue;

    /*
     * Thread implementations are just multiple queue type implemenations,
     * Below are the various link lists currently necessary
     * It is possible for a thread to be on multiple, or even all the
     * queues at once, much care must be taken during queue manipulation.
     *
     * The pthread structure must be locked before you can even look at
     * the link lists.
     */ 

    struct pthread          *pll;       /* ALL threads, in any state */
    /* struct pthread       *rll;        Current run queue, before resced */
    struct pthread          *sll;       /* For sleeping threads */
    struct pthread          *next;      /* Standard for mutexes, etc ... */
    /* struct pthread           *fd_next;    For kernel fd operations */

    int                     fd;         /* Used when thread waiting on fd */

    semaphore               lock;

    /* Data that doesn't need to be locked */
    void                    *ret;
    int                     error;
    const void              **specific_data;
};

    typedef struct pthread *        pthread_t;

现在让我们看下面的代码来打印线程的ID:

#include <stdio.h> 
#include <stdlib.h> 
#include <pthread.h> 
void* calls(void* ptr) 
{ 
    // using pthread_self() get current thread id 
    printf("In function \nthread id = %ld\n", pthread_self()); 
    pthread_exit(NULL); 
    return NULL; 
} 

int main() 
{ 
    pthread_t thread; // declare thread 
    pthread_create(&thread, NULL, calls, NULL); 
    printf("In main \nthread id = %ld\n", thread);  
    pthread_join(thread, NULL);  
    return 0; 
} 

我系统的输出是:

In main 
thread id = 140289852200704
In function 
thread id = 140289852200704

从pthread.h文件(上图)可知,pthread是一个结构体,代码中的thread是指向结构体pthread的指针(因为pthread_ttypdef struct pthread*)。为什么打印这个指针会给我们线程 ID?

【问题讨论】:

  • 你可能想看看这个:*.com/questions/33285562/…
  • 为什么不呢?使用描述符结构的基地址是为复杂对象传递伪不透明标记的一种非常常见的方法。
  • @Martin James 你能解释一下吗?请提供链接。
  • 线程 ID 不是数字。您可以编写代码以将线程 ID 作为数字传递,并且将打印一些数字。但这个数字绝不是线程 ID。线程 ID 是 pthread_t 类型的值。它们无法打印。他们甚至不能直接是compared
  • @KrishnaKanthYenumula 链接?想想看 - 你有一个复杂的数据/代码/线程/用户需要访问的任何东西,一个文件系统,一个服务器,一个线程池,等等。几乎总是会有一个包含管理数据、函数/方法指针/引用等的根结构/对象,一个在系统创建时动态分配的根,因此具有唯一的基地址。那是您的令牌,其他系统元素只需要该令牌即可访问子系统的服务。

标签: c multithreading struct pthreads


【解决方案1】:

从 pthread.h 文件(上图)中,pthread 是一个结构体,thread 在 code 是指向结构 pthread 的指针(因为 pthread_ttypdef struct pthread*)。

明确一点:在那个实现中pthread_t 是一个指向结构的类型。我想这对于 pthreads 实现来说很常见,但要小心避免将特定实现的细节误认为规范或所有实现的一般特征。例如,它也可以是其他实现中的整数索引,以及其他各种可能性。

为什么打印这个指针会给我们线程 身份证?

因为它线程ID。而且因为您很幸运,使用 %d 格式化指令打印它所产生的未定义行为在两个地方都以相同的方式表现出来。

您可能通过查看实现的pthread_t 的定义而对自己造成了伤害。你不需要知道这些细节来使用 pthreads,事实上它们对你一点帮助也没有。该类型应被视为不透明。

回答这个问题你真正需要了解的是pthread_create()写入变量thread的值是创建线程的ID,pthread_self()返回的值是调用线程的线程ID。自然,每种获取线程 ID 的机制都会为同一个线程生成相同的 ID。

【讨论】: