【问题标题】:Which Linux syscall is used to get a thread's ID?哪个 Linux 系统调用用于获取线程的 ID?
【发布时间】:2013-10-13 20:58:02
【问题描述】:

我必须实现一个作为pthread_self() 的包装函数来获取pthread ID,但我一直在搜索并且没有找到执行此操作的系统调用。阅读 Stack O 的另一篇文章。我知道 clone() 用于创建线程,而且我可以使用 ptrace() 跟踪系统调用,但在手动跟踪之前......有人知道哪个系统调用是吗?

【问题讨论】:

    标签: multithreading unix operating-system pthreads


    【解决方案1】:

    一个 linux 进程线程有 3 个不同的 ID:pid、pthread id 和 tid。

    “pid”是全局的,相当于父进程id,可以通过“getpid()”轻松获取。此值是唯一的,但仅在分配给定 ID 的活动进程的持续时间内。在进程终止并产生新进程后,该值可能会为新进程“回收”。这个值在一个进程内的所有线程中都是相同的。该值是您将在 top、htop、'ps -ef' 和 pidstat 中看到的值。

    “pthread id”由 pthread_create() 和 phtread_self() 报告。这是值仅在进程内是唯一的,并且仅在分配线程的持续时间内是唯一的。当线程终止并产生时,该值可能会被“回收”。该值在整个系统中不是唯一的,在已终止和启动的线程中也不是唯一的。这个值在程序之外是不可见的。此值是不透明的,可能是指针或结构,具体取决于平台。

    “tid”线程 id 由 gettid() 报告。这是在 Linux 2.4 中引入的,在其他平台上似乎不可用。该值在流程内和整个系统中是唯一的。该值由 top 和 htop 以及 'pidstat -t' 报告。我不是 100% 确定,但怀疑这个值可以在进程终止和生成时“回收”。这是在显示线程时出现在 Linux 工具“top”、“htop”、“pidstat -t”和“ps -efL”中的值。

    gettid 的文档:linux.die.net/gettid

    你可以通过以下方式获取'gettid()':

    #include <sys/types.h>
    #include <sys/syscall.h>
    #include <pthread.h>
    

    我的 CentOS 6.5 没有正确设置并且缺少 gettid 原型,尽管文档说它应该通过上面的#includes 呈现。这是一个模仿“gettid”的宏:

    #ifndef gettid
    // equivalent to:  pid_t  gettid(void)
    #define gettid() syscall(SYS_gettid)
    #endif
    

    请注意,由于这是一个 syscall(),因此您可以通过缓存结果并避免重复使用 syscall() 来提高效率。

    【讨论】:

      【解决方案2】:

      系统调用0xe0,gettid()怎么样?

      gettid() 返回调用者的线程 ID (TID)。在单线程进程中,线程 ID 等于进程 ID(PID,由 getpid(2) 返回)。在多线程进程中,所有线程都有相同的 PID,但每个线程都有唯一的 TID。更多详细信息,请参阅 clone(2) 中对 CLONE_THREAD 的讨论。

      【讨论】:

      • 但我发现 gettid 返回的是操作系统特定的线程 ID,而不是进程的相关 ID……或者我可能感到困惑。而且,它会在进程内返回TID吗?
      • 引用:“此调用返回的线程 ID 与 POSIX 线程 ID 不同”所以?
      • 嗯,看来你是对的。这两个是不一样的。 pthreads_self 的手册页甚至这样说:“线程标识符应该被认为是不透明的:在 pthreads 调用中使用线程 ID 的任何尝试都是不可移植的,并且可能导致未指定的结果。pthread_self() 返回的线程 ID 不一样调用 gettid(2) 返回的内核线程 ID。"
      • 但是,如果您使用 libc 克隆,您应该将 TID 作为返回值。来自 clone(2) 手册页:“新线程的 TID 可作为返回给 clone() 调用者的函数结果,并且线程可以使用 gettid(2) 获取自己的 TID。”
      • 总之,如果你使用clone(),你应该得到TID作为返回值,并且能够使用gettid()再次得到相同的TID。如果您不使用 pthread_create() 创建线程,那么想要获得 pthread_self() 将返回的数字是没有意义的,或者是否存在?
      【解决方案3】:

      在 glibc 中,pthread_self() 不进行系统调用,而是返回指向位于 TSD 段中的 struct pthread 的指针。

      【讨论】:

      • 是的,但是我需要实现能够获取线程ID的系统调用
      【解决方案4】:

      这可能会有所帮助。

      UINT32 tid= syscall(SYS_gettid);

      【讨论】:

        猜你喜欢
        • 2014-05-17
        • 2012-03-17
        • 1970-01-01
        • 2013-10-30
        • 1970-01-01
        • 2021-01-22
        • 2014-06-08
        • 2011-10-18
        • 1970-01-01
        相关资源
        最近更新 更多