什么是_GLIBCXX_USE_NANOSLEEP?

jog*_*pan 44 c++ gcc sleep glibc

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

  • C++/4.7.1/x86_64的未知-Linux的GNU /比特/ 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 */
Run Code Online (Sandbox Code Playgroud)

而在线程中,定义std::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;

但请注意Jonathan的回答中给出的关于GCC 4.8和4.9的进一步细节.

Jon*_*ely 70

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

在您的情况下configure确定POSIX nanosleep()功能不可用并且未定义宏.但是,就像你说的,nanosleep() 你的系统上.configure除非您使用该--enable-libstdcxx-time选项(在libstdc ++手册配置章节中记录,而不是GCC配置文档),否则它未启用的原因是它的检查甚至都不会运行

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

是, --enable-libstdcxx-time

  • nanosleep()函数和宏之间是否存在真正的关系?在ctime/time.h中声明nanosleep()似乎并不依赖于宏定义.

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

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

它很顽皮,没有支持,但会起作用.宏是一个内部实现细节,应由configure而不是用户设置,更改实现内部宏的定义可能会破坏事物.但在这种情况下它不会,因为唯一依赖它的代码在标题中,没有库代码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.

  • **这是一个很好的答案,值得许多赞成.**(我正在使用正确拼写的选项进行重建,并在完成后报告,但无论如何,这解释了我感兴趣的背景.) (3认同)