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

How to get thread object by id?

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

如果可以避免,我不推荐这个。即使在它可以工作的平台上,它也是一个糟糕的设计。我把它作为一个学术练习来满足好奇心。

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());
}

输出:

Thread ran.

thread joined.

error: 3

thread::join failed: No such process

如您所见,pthread_join() 第一次调用时没有 return 错误,表明线程确实已加入。第二次是 returns ESRCH 因为线程已经加入了;与 t1.join().

相同

请注意,如果构建实现只是为了检查 pthread_t 是否为非 0,t1.joinable() 仍将 return 为真。std::thread 将在没有的情况下被销毁超出范围时出错;当 运行 Asan/Ubsan/Tsan 时,我没有检测到任何错误; YMMV.