名为 _GLIBCXX_USE_NANOSLEEP 的预处理器宏出现在两个标准头文件中:
在 GCC 4.7.1(Linux,64 位)的默认版本中,c++config.h 唯一包含的是以下注释:
/* Defined if nanosleep is available. */
/* #undef _GLIBCXX_USE_NANOSLEEP */
而在thread中,
std::this_thread::sleep_for()
和std::this_thread::sleep_until()
的定义取决于要定义的宏。如果未定义,则这两个函数(尽管 C++ 标准要求如此)也不会被定义。
在我的系统(glibc 2.15)上,尽管
nanosleep()
函数(在 ctime
中声明)存在并且可以运行,但未定义宏。
我想知道这是怎么回事以及如何处理。具体来说:
nanosleep()
函数和宏真的有关系吗? nanosleep()
/ctime
中的time.h
声明似乎不依赖于或定义宏。-D
选项是否存在任何特定风险(如此相关问题中所建议)?如果我在 nanosleep()
不可用的系统上执行此操作怎么办?我怎样才能真正找到答案?更新 从GCC 4.8开始,libstdc++中自动包含对
std::this_thread::sleep_for()
等的支持。不再需要配置标志。来自GCC 4.8 变更日志:
this_thread::sleep_for()、this_thread::sleep_until() 和 this_thread::yield() 的定义不需要配置选项 --enable-libstdcxx-time;
但请注意 Jonathan 的回答中给出的 GCC 4.8 和 4.9 的更多详细信息。
当构建 libstdc++ 时,其
configure
脚本会测试您的系统以查看支持哪些功能,并根据结果在 c++config.h
中定义(或取消定义)各种宏
在您的情况下
configure
确定POSIXnanosleep()
函数不可用并且未定义宏。 但是,正如您所说,nanosleep()
在您的系统上可用。
configure
未启用它的原因是,在 4.9.0 之前的 GCC 版本中,除非使用
nanosleep
选项,否则对
--enable-libstdcxx-time
的检查甚至不会运行(记录在libstdc++ 手册,而不是 GCC 配置文档)。 GCC 4.9.0 的检查得到了改进,本答案的其余部分仅适用于旧版本。
按照这篇文章的建议,在构建 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()
,但我还没有时间研究它们。更新:我已经进行了一些更改,以便在没有 --enable-libstdcxx-time
的情况下构建 GCC 4.8 仍将定义
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
。