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

fre*_*ish 5 c++ std c++11 stdthread

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

Bra*_*red 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());
}
Run Code Online (Sandbox Code Playgroud)

输出:

线程运行了。

线程加入。

错误:3

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

正如您所看到的,pthread_join()第一次调用时没有返回错误,表明线程确实已加入。第二次返回是ESRCH因为线程已经加入;与 相同t1.join()

请注意,t1.joinable()如果构建实现只是为了检查 the 是否pthread_t非 0,则仍将返回 true std::thread。当超出范围时,将被销毁而不会出现错误;使用 Asan/Ubsan/Tsan 运行时,我没有检测到任何错误;YMMV。