【问题标题】:Implementation of Microsoft's std::thread incompatible with specification?微软的 std::thread 的实现与规范不兼容?
【发布时间】:2021-02-21 01:07:15
【问题描述】:

参考:

检查 std::thread 对象是否标识了一个活动线程 执行。

具体来说,如果 get_id() != std::thread::id() 则返回 true

最后,函数所做的只是将线程的标识符与 0 进行比较。

https://en.cppreference.com/w/cpp/thread/thread/joinable

实际代码(线程):

_NODISCARD bool joinable() const noexcept {
    return _Thr._Id != 0;
}

【问题讨论】:

  • 你有没有偷看std::thread::id是什么?
  • 我还没有,无论如何。文档指出,如果由执行的活动线程调用,该函数应该返回 false,而我开始潜伏于此的原因并非如此。该函数与 0 进行比较。
  • 如果它的行为方式相同,则实现无关紧要。如果您在使用std::thread 时遇到问题,请使用minimal reproducible example 发布新问题。 Visual Studio 实现正确且有效,问题很可能出在您的代码中
  • 不调用 by,调用 on 与活动线程关联的 std::thread。要么您误解了规范,要么误解了 Microsoft 的实施。甚至可能两者兼而有之。无论哪种方式,它的行为都符合规定。
  • @Vega4 "线程是否由当前活动线程执行" 这不是joinable 所做的。从您链接的页面:“检查是否 std::thread 对象 标识一个活动的执行线程” .您调用joinable 来自的线程无关紧要。

标签: c++ multithreading visual-studio


【解决方案1】:

引用的要求说“如果get_id() != std::thread::id() 则返回真”

要将其放入代码中,对名为 std::thread 的类型为 thr 的对象的测试是:

thr.get_id() != std::thread::id()

注意std::thread::id() 只是一个std::thread::id 类型的默认构造对象。它具有以下属性:

std::thread thr;             // thr.get_id() == std::thread::id()
std::thread thr1(something); // thr.get_id() != std::thread::id()
thr1.detach();               // thr.get_id() == std::thread::id()

您可以通过调用std::this_thread::get_id() 而不是std::thread::id() 获得当前正在执行的线程的ID(是的,名称看起来很相似,而且可能会造成混淆)

最终,在线程对象上调用joinable() 只会告诉您对该对象的join() 调用是否有效。如果调用join() 无效,调用它会抛出异常。

至于实现,我编写了 Dinkumware 实现,它是 Microsoft 代码的基础(他们可能在过去几年中更改了它)。标准并没有说明std::thread::id 的内容应该是什么。在 Dinkumware 实现中,它只保存一个无符号整数值。对于不可连接的线程,该值为 0;对于可连接的线程,它的值不是 0。因此通过与 0 进行比较来实现 joinable() 是正确的。

【讨论】:

    猜你喜欢
    • 2013-07-12
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 1970-01-01
    • 2020-01-10
    • 2018-02-13
    • 1970-01-01
    • 2018-06-27
    相关资源
    最近更新 更多