【问题标题】:Should not std::thread::id default constructor create a "NULL" id?std::thread::id 默认构造函数不应该创建一个“NULL”id吗?
【发布时间】:2013-04-10 11:53:31
【问题描述】:

以下代码在我的 gcc 版本 4.8.0 中失败:

#include <thread>
#include <cassert>

int main() {
    std::thread::id nobody;

    assert( nobody != std::this_thread::get_id() );
};

这种行为正确吗?

【问题讨论】:

  • @Ali 也许他的 libstdc++ 已经过时了?

标签: c++ linux gcc c++11


【解决方案1】:

更新: Jonathan Wakely 好心地查看了he says (below in comments) -pthread 必须同时传递给编译器和链接器的问题。如果我这样做,代码也不会因 gcc 4.7.2 而失败。所以答案显然与引用的电子邮件无关。谢谢乔纳森!


以下是来自 gcc 开发者Jonathan Wakely's mail 的引用,写于 2011 年:

我们的 std::thread::id 上的所有比较运算符都依赖于 undefined 行为,因为我们的 thread::id 只是一个 pthread_t。

[...]

2) operator== 使用 pthread_equal,未定义为无效 线程 ID,POSIX 说:

   If either t1 or t2 are not valid thread IDs, the behavior is undefined.
虽然它是两年前写的,但它可能仍然适用。 目前我无法检查 gcc 代码库以说明更多信息。

奇怪。以下代码:

#include <iostream>
#include <thread>

int main() {

    std::cout << "Started" << std::endl;

    std::thread::id nobody;

    if ( nobody != std::this_thread::get_id() )  {

      std::cout << "OK" << std::endl;
    }

    std::cout << "Finished" << std::endl;
}

产生:

Started 
OK 
Finished

检查here。但是,您的代码在 4.7.2 中确实失败了。

【讨论】:

  • 如果您不将 -pthread 传递给编译器和链接器,它只会在 4.7.2 中失败。大概pthread_equal在你不链接到libpthread.so时总是返回true,我猜这是&lt;thread&gt;中的一个错误,所以我最好修复它
  • 明确一点,我认为这与您引用的邮件无关,与尝试使用std::thread 而不是与-pthread 链接有关
  • @JonathanWakely 是的,现在我明白了,我马上更新答案。
  • 现在是gcc.gnu.org/bugzilla/show_bug.cgi?id=57060 -- 但是要使用 GCC 的 std::thread 获得正确的行为,您应该始终使用 -pthread
【解决方案2】:

我无法访问 C++11 标准,但来自最新的标准草案 n3485 [thread.thread.id]

thread::id 类型的对象为每个执行线程提供唯一标识符,并为所有不代表执行线程的线程对象提供一个不同的值 (30.3.1)

紧随其后

id() noexcept; 效果:构造一个 id 类型的对象。 后置条件:构造的对象不代表执行线程。

这似乎暗示您所观察到的是 gcc 中的一个错误

【讨论】:

    猜你喜欢
    • 2012-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多