45

一个名为 _GLIBCXX_USE_NANOSLEEP 的预处理器宏出现在两个标准头文件中:

  • c++/4.7.1/x86_64-unknown-linux-gnu/bits/c++config.h
  • c++/4.7.1/线程

在 GCC 4.7.1(Linux,64 位)的默认构建中, c++config.h包含的唯一内容是以下注释:

/* Defined if nanosleep is available. */
/* #undef _GLIBCXX_USE_NANOSLEEP */

而在threadstd::this_thread::sleep_for()中,和的定义std::this_thread::sleep_until()取决于要定义的宏。如果没有定义,这两个函数——尽管 C++ 标准要求——也不会被定义。

在我的系统(glibc 2.15)上,宏没有定义,尽管nanosleep()函数(在 中声明ctime)存在并且可以运行。

我想知道这是怎么回事以及如何处理它。具体来说:

  • 正如这篇文章所建议的那样,在构建 GCC 以默认激活此宏时是否应该使用配置选项?(我在构建过程的在线文档中找不到任何内容。)
  • nanosleep()函数和宏之间真的有关系吗?nanosleep()in ctime/的声明time.h似乎不依赖或定义宏。
  • -D在我自己的头文件中定义宏或作为命令行上的一个选项(如相关问题中所建议的那样)是否存在任何特定风险?如果我在一个nanosleep()不可用的系统上执行此操作,我如何才能真正找到?

更新从 GCC 4.8 开始,std::this_thread::sleep_for()libstdc++ 中自动包含对等的支持。不再需要配置标志。从GCC 4.8 更改日志

this_thread::sleep_for()、this_thread::sleep_until() 和 this_thread::yield() 的定义不需要配置选项 --enable-libstdcxx-time;

但请注意乔纳森的回答中给出的 GCC 4.8 和 4.9 的更多细节。

4

1 回答 1

73

构建 libstdc++ 时,它的configure脚本会测试您的系统以查看支持哪些功能,并根据结果定义(或取消定义)各种宏c++config.h

在您的情况下configure,确定 POSIXnanosleep()函数不可用且未定义宏。但是,正如您所说,在您的系统上可用nanosleep() 未启用它的原因是,除非您使用该选项,configure否则对它的检查甚至不会运行(记录在 libstdc++ 手册的配置章节中,而不是 GCC 配置文档中)--enable-libstdcxx-time

  • 正如这篇文章所建议的,在构建 GCC 以默认激活此宏时,是否应该使用配置选项?(我在构建过程的在线文档中找不到任何内容。)

是的,--enable-libstdcxx-time

  • nanosleep() 函数和宏之间真的有关系吗?ctime/time.h 中 nanosleep() 的声明似乎不依赖或定义宏。

glibc 函数的声明不依赖于 libstdc++ 的宏,不。但是宏告诉 libstdc++ 是否使用该函数。

  • 在我自己的头文件中定义宏或作为命令行上的 -D 选项(如相关问题中所建议的那样)是否存在任何特定风险?如果我在 nanosleep() 不可用的系统上执行此操作,我如何才能真正找到?

它很顽皮,不受支持,但会起作用。宏是一个内部实现细节,应该由配置而不是由用户设置,并且更改实现的内部宏的定义可能会破坏事情。但在这种情况下,它不会因为唯一依赖它的代码在头文件中,没有库代码libstdc++.so受到影响。

但是最好重新安装 GCC 并使用该--enable-libstdcxx-time选项,或者如果这不可能,请编辑您c++config.h以将宏定义为 true。

如果您在nanosleep()不可用的其他系统上定义它,您将在#include <thread>.

我有一些改进该配置的想法,因此默认情况下会检查nanosleep()sched_yield()检查,但我还没有时间处理它们。

更新:我已经进行了一些更改,以便在没有构建 GCC 4.8 的情况下--enable-libstdcxx-time仍将定义std::this_thread::yield()(作为无操作)并将实现std::this_thread::sleep_for()std::this_thread::sleep_until()使用较低的分辨率::sleep()::usleep()功能而不是::nanosleep(). 不过定义还是比较好--enable-libstdcxx-time

另一个更新: GCC 4.9.0 已经发布,现在默认在已知支持它们的平台上nanosleep自动启用。sched_yield不再需要使用--enable-libstdcxx-time.

于 2012-10-18T18:58:21.647 回答