Linux上的pthread_self

时间:2017-04-18 12:09:44

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

我有以下小代码片段:

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等

1 个答案:

答案 0 :(得分:1)

或多或少如下:首先,当pthread_self()在标准C库中实现时,不需要将其链接到与-lpthreads链接。

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

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

这就是为什么当你没有链接Pthreads和实际的POSIX线程ID时你得到0。

自定义主题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<pthread_t, int> 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()]...
}