【问题标题】:How do I get a thread ID from an arbitrary pthread_t?如何从任意 pthread_t 获取线程 ID?
【发布时间】:2010-10-08 04:36:40
【问题描述】:

我有一个 pthread_t,我想更改它的 CPU 关联性。问题是我使用的是 glibc 2.3.2,它没有 pthread_setaffinity_np()。不过没关系,因为 pthread_setaffinity_np() 本身是 sched_setaffinity() 的包装器,可以通过传递线程 ID 而不是进程 ID 来调用它来设置任意线程的亲和性。

但是 ... sched_setaffinity 可以使用的线程ID 是操作系统线程ID,您可以从gettid() 系统调用中获得这种ID。 这与不透明类型pthread_t 不同,gettid() 将只返回当前线程 的线程ID。我需要能够设置任意线程的 CPU 亲和性。

不幸的是,我无法访问 pthread 的私有部分,这会让我通过将 pthread_t 强制转换为 struct pthread * 来窃取线程 ID。我猜这样会更好,因为依赖私有实现会带来更多的麻烦。

我也一直在阅读 pthread_getunique_np 函数,但是它返回一个“唯一的整数标识符”——我不认为它在任何形状或形式上都等同于操作系统线程 ID。

因此,问题是:如何从任意 pthread_t 获取线程 ID?

【问题讨论】:

    标签: c linux unix pthreads system-calls


    【解决方案1】:

    由于pthreads 不需要用Linux 线程(或内核线程,就此而言)实现,并且某些实现完全是用户级或混合的,pthreads 接口不提供函数访问这些实现细节,因为它们是不可移植的(即使在 Linux 上的 pthreads 实现中)。使用这些的线程库可以将其作为扩展提供,但似乎没有这样做。

    除了访问线程库的内部数据结构(可以理解的是,您不希望这样做,尽管根据您对处理器亲和性和 Linux 线程 ID 的假设,您的代码无论如何都不会是可移植的),您也许可以玩个把戏在创建时,如果您控制创建线程的代码:

    pthread_create() 一个调用gettid() 的入口函数(顺便说一下,您可能不得不直接使用syscall 宏,因为它并不总是由libc 导出),将结果存储在某处,然后调用原来的入口函数。如果您有多个线程具有相同的入口函数,您可以将递增的指针传递到 arg 参数中的数组到 pthread_create,然后将其传递给您创建的入口函数以存储线程 ID。 pthread_t 以相同的顺序返回 pthread_create 的值,然后您将能够根据它们的 pthread_t 值查找您创建的所有线程的 Linux 线程 ID。

    这个技巧是否值得,取决于在您的情况下设置 CPU 亲和性的重要性,而不是不访问线程库的内部结构或取决于提供pthread_setaffinity_np 的线程库。

    【讨论】:

      【解决方案2】:

      实际上pthread_self 返回pthread_t 而不是您可以使用的整数线程ID,以下帮助函数将以可移植的方式跨不同POSIX 系统为您提供。

      uint64_t gettid() {
          pthread_t ptid = pthread_self();
          uint64_t threadId = 0;
          memcpy(&threadId, &ptid, std::min(sizeof(threadId), sizeof(ptid)));
          return threadId;
      }
      

      【讨论】:

      • pthread_t tid = pthread_self(); 在主线程上工作,但在另一个线程上不行?在调用pthread_create 之后,我的exe 崩溃从__start_routine 调用。
      【解决方案3】:
      pthread_t pthread_self()
      

      这个返回当前的pthread_t,也就是线程id,可以转换成“unsigned int”类型,

      【讨论】:

      • 其实unsigned long int.
      • pthread_self 返回类似于 pthread 使用的内部结构的地址。这不是系统调用 gettid() 返回的操作系统分配的线程 ID。
      【解决方案4】:

      glibc 2.24 中,返回的 pthread_t 只是指向不透明 struct pthread 的指针。您可以在nptl/descr.h 中查找定义。

      【讨论】:

        【解决方案5】:

        我建议使用共享 int 数组的简单解决方法,您可以在其中写入线程中的线程 id 以便以后访问它。

        希望对您有所帮助。

        【讨论】:

        • 不需要mmap,反正线程共享同一个内存。
        猜你喜欢
        • 1970-01-01
        • 2011-01-12
        • 1970-01-01
        • 2011-03-18
        • 2013-12-09
        • 2010-12-13
        • 2017-05-21
        • 1970-01-01
        • 2012-12-14
        相关资源
        最近更新 更多