Linux 上的pthread_self

pthread_self on Linux

提问人:Dr. Debasish Jana 提问时间:4/18/2017 最后编辑:Dr. Debasish Jana 更新时间:4/19/2017 访问量:2188

问:

我有以下小代码片段:

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

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

0

当我与pthread链接时,如下所示:

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

输出为:

139675118393152

当与 -lpthreads 链接时,我是否可以获取从实际 POSIX 线程 ID 到线程唯一的某个索引的映射?我想要一个全局数组,其中包含一些特定于线程的值,并且需要使用线程 ID 作为数组索引,无法处理139675118393152,例如,需要将其映射到 1、2 等

C++ Linux pthreads g++4.9

评论


答:

1赞 cbuchart 4/18/2017 #1

或多或少是这样的:首先,正如在标准C库中实现的那样,它不需要链接就可以被链接。pthread_self()-lpthreads

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

此指针初始化为 NULL (0),但 Pthreads 库(链接时)会更改它,以便它现在指向当前线程标头结构。

这就是为什么在不与 Pthreads 链接时得到 0 时得到 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);
}

另一种选择可能是使用全局结构,并将线程 ID 与作为参数传递的数组索引链接起来。您必须注意竞争条件(为简单起见,此处省略)。您还应该关心不是以这种方式创建的线程的大小写(如果可能),因为该值不会存在于映射中。std::map<pthread_t, int> g_thread_idspthread_self()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()]...
}

评论

0赞 Dr. Debasish Jana 4/19/2017
编辑了我的 Qs,如何将这个长线程 ID 映射到 1、2 等 ID
0赞 cbuchart 4/19/2017
我认为最简单的方法是在创建时分配一个 ID,作为线程 main 函数的参数。
0赞 Dr. Debasish Jana 4/19/2017
但是,我想从pthread_self()之类的任何地方获取它