如何通过id获取线程对象?

时间:2017-03-27 09:52:48

标签: c++ c++11 std stdthread

假设某个线程有一些其他线程的std::thread::id myId。现在,我想要检索与std::thread相关联的myId对象,以便我可以.join()它。是std有可能吗?或者我必须手动跟踪它吗?

1 个答案:

答案 0 :(得分:3)

如果可以避免,我不建议您这样做。即使在可以使用的平台上,它的设计也很糟糕。我将其作为满足好奇心的学术练习。

AFIK没有标准方法。如果您不需要便携性,而您真的想要这样做...

在某些平台(例如Mac和Linux)上,std::thread只是您已经拥有的基础pthread_t的包装,因为它与您已经拥有的std::thread::id相同有。换句话说,您可以将其转换为pthread_t并将其传递给pthread_join。与之关联的std::thread对象的行为 应该与您在其上调用join()时的行为一样。

示例程序(在macOS 10.13上测试):

auto t1 = std::thread([]() {
    printf("Thread ran.\n");
});

auto id = t1.get_id();
pthread_t* ptr = (pthread_t*)&id;
int ret = pthread_join(*ptr, nullptr);
if (ret == 0) {
    printf("thread joined.\n");
}

ret = pthread_join(*ptr, nullptr);
if (ret != 0) {
    printf("error: %d\n", ret);
}

try {
    t1.join();
} catch (std::system_error& e) {
    printf("%s\n", e.what());
}

输出:

  

线程跑了。

     

线程已加入。

     

错误:3

     

thread :: join失败:没有这样的过程

您可以看到pthread_join()在第一次被调用时没有返回错误,表明确实已加入了线程。它第二次返回ESRCH,因为该线程已经加入;与t1.join()相同。

请注意,如果将实现构建为仅检查t1.joinable()是否为非0,则pthread_t仍将返回true。std::thread退出时将被无错误破坏。范围;使用Asan / Ubsan / Tsan运行时,我没有发现任何错误; YMMV。