pthread_self on Linux

pthread_self on Linux

本文关键字:Linux on self pthread      更新时间:2023-10-16

我有以下小型代码段:

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等。p>

或多或少是如下:首先,由于在标准C库中实现了pthread_self(),因此不需要链接到-lpthreads

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

此指针初始化为null(0(,但是pthreads库(链接时(更改它,因此它现在指向当前的线程标头结构。

这就是为什么当您与pthreads链接时不链接到0时获得0的原因。

自定义线程IDS

您可以在创建时为每个线程分配一个自定义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()]...
}