如何在c 11中获取整数线程ID

新手上路,请多包涵

c++11 有可能获取当前线程 id,但它不能转换为整数类型:

 cout<<std::this_thread::get_id()<<endl;

输出:139918771783456

 cout<<(uint64_t)std::this_thread::get_id()<<endl;

错误:从类型“std::thread::id”到类型“uint64_t”的无效转换与其他类型相同:从类型“std::thread::id”到类型“uint32_t”的无效转换

我真的不想进行指针转换来获取整数线程 id。有没有一些合理的方法(标准,因为我希望它是可移植的)来做到这一点?

原文由 NoSenseEtAl 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

可移植的解决方案是将您自己生成的 ID 传递到线程中。

 int id = 0;
for(auto& work_item : all_work) {
    std::async(std::launch::async, [id,&work_item]{ work_item(id); });
    ++id;
}

std::thread::id 类型仅用于比较,而不用于算术(即,正如它在罐头上所说:一个 _标识符_)。甚至由 operator<< 生成的文本表示也是 未指定 的,因此您不能依赖它作为数字的表示。

您还可以使用 std::thread::id 值映射到您自己的 id,并在线程之间共享此映射(适当同步),而不是直接传递 id。

原文由 R. Martinho Fernandes 发布,翻译遵循 CC BY-SA 3.0 许可协议

另一种选择:

 #include <atomic>

static std::atomic<unsigned long long> thread_counter;

unsigned long long thread_id() {
    thread_local unsigned long long tid = ++thread_counter;
    return tid;
}

g++ 在 x86 64 位中为这个函数生成的代码只是:

 _Z9thread_idv:
        cmp     BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 0
        je      .L2
        mov     rax, QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff
        ret
.L2:
        mov     eax, 1
        lock xadd       QWORD PTR _ZL14thread_counter[rip], rax
        mov     BYTE PTR fs:_ZGVZ9thread_idvE3tid@tpoff, 1
        mov     QWORD PTR fs:_ZZ9thread_idvE3tid@tpoff, rax
        ret
_ZGVZ9thread_idvE3tid:
        .zero   8
_ZZ9thread_idvE3tid:
        .zero   8

即没有任何同步的单个分支,除了您第一次调用该函数外,它将被正确预测。之后只是一个没有同步的内存访问。

原文由 6502 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题