c++ - Linux 上的 pthread_self

标签 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 等

最佳答案

大致如下:首先,如pthread_self()在标准 C 库中实现,它不需要链接到 -lpthreads。 .

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

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

这就是为什么在不链接 Pthreads 时得到 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<pthread_t, int> g_thread_ids构造并链接来自 pthread_self() 的线程 ID数组索引作为参数传递。您必须注意竞争条件(为简单起见此处省略)。您还应该关心未以这种方式创建的线程的情况(如果可能),因为 pthread_self()值将不存在于 map 中。

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()]...
}

关于c++ - Linux 上的 pthread_self,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43471743/

相关文章:

C++ 子字符串/字符串操作

c++ - 中间函数

c++ - 在 fork 后删除 condition_variable 时提升崩溃

c - 我的线程不是并行的,它们是串行的。如何使它们平行?

c - Mutex 的最佳替代方案——执行时间更短

c++ - 在 visual studio 2008 中输出

c++ - 在 Windows 小型转储文件中嵌入线程名称

linux - 在 Linux 上使用 Cocos2dx 制作游戏

linux - 如何在内核模块中访问/dev/shm 下由用户空间进程创建的 tmpfs 文件?

c++ - pthread_create ENOMEM 大约 32000 个线程