【问题标题】:pthread_self on LinuxLinux 上的 pthread_self
【发布时间】:2017-09-14 06:24:57
【问题描述】:

我有如下小代码sn-p:

int main()
{
  pthread_t t = pthread_self();
  std::cout << t << std::endl;
  return 0;
}

当我在没有任何库的情况下使用 g++ 4.9.2 在 Linux 上编译+链接时,输出为:

0

当我如下链接 pthread 时:

g++ test.c -o test -lpthread; ./test

输出是:

139675118393152

当与 -lpthreads 链接时,我能否获得从实际 POSIX 线程 ID 到某个线程唯一索引的映射?我想要一个全局数组,它有一些线程特定的值要使用,并且需要使用线程 id 作为数组索引,不能处理 139675118393152,例如,需要将其映射到 1、2 等

【问题讨论】:

    标签: c++ linux pthreads g++4.9


    【解决方案1】:

    大致如下:首先,由于pthread_self()是在标准C库中实现的,所以不需要链接到-lpthreads

    现在,pthread_self() 使用全局变量、指向 TCB(线程控制块)的指针来存储线程信息,包括 ID(在进程中唯一)。

    这个指针被初始化为 NULL (0),但是 Pthreads 库(当链接时)改变了它,所以它现在指向当前的线程头结构。

    这就是为什么在不与 Pthread 链接时会得到 0,而在这样做时会得到实际的 POSIX 线程 ID。

    自定义线程 ID

    您可以在创建时为每个线程分配一个自定义 ID,并将该值用作数组的索引。

    void* thread_function(void* data) {
      assert(data);
      const int id = *((int*)data);
    
      // g_array[id]...
    }
    
    int main() {
      // ...
      pthread_t t0;
      int t0id = 0; // this variable must exist when the thread starts
      pthread_create(&t0, NULL, thread_function, &t0id);
    
      pthread_t t1;
      int t1id = 1; // this variable must exist when the thread starts
      pthread_create(&t1, NULL, thread_function, &t1id);
      // ...
    
      pthread_join(t0, NULL);
      pthread_join(t1, NULL);
    }
    

    另一种选择可能是使用全局std::map&lt;pthread_t, int&gt; g_thread_ids 结构并链接来自pthread_self() 的线程ID 和作为参数传递的数组索引。您必须小心竞争条件(为简单起见,此处省略)。您还应该关心不是以这种方式创建的线程的情况(如果可能),因为映射中不存在pthread_self() 值。

    std::map<pthread_t, int> g_thread_ids;
    
    int get_thread_index() { // note: critical section
       if (g_thread_ids.find(pthread_self()) == g_thread_ids.end()) return -1;
       return g_thread_ids[pthread_self()];
    }
    
    void* thread_function(void* data) {
      assert(data);
      const int id = *((int*)data); // read the index from caller
      g_thread_ids[pthread_self()] = id; // note: critical section
    
      // g_array[get_thread_index()]...
    }
    

    【讨论】:

    • 编辑了我的 Qs,如何将这个长线程 id 映射到 1、2 等 id
    • 我认为最简单的方法是在创建时分配一个ID,作为线程main函数的参数。
    • 但是,我想从 pthread_self() 之类的任何地方获取它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多