Вопрос по sleep, gcc, glibc, c++ – Что такое _GLIBCXX_USE_NANOSLEEP?

43

Макрос препроцессора с именем _GLIBCXX_USE_NANOSLEEP появляется в двух стандартных заголовочных файлах:

c++/4.7.1/x86_64-unknown-linux-gnu/bits/c++config.h c++/4.7.1/thread

В стандартной сборке GCC 4.7.1 (Linux, 64-bit) единственноеc++config.h включает в себя этот комментарий:

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

Тогда как вthreadопределениеstd::this_thread::sleep_for() а такжеstd::this_thread::sleep_until() зависит от макроса, который будет определен. Если это не определено, обе функции & # x2013; хотя требуется стандартом C ++ & # x2013; также не будет определен.

В моей системе (glibc 2.15) макрос не определен, хотяnanosleep() функция (объявлена вctime) существует и работает.

Мне бы хотелось узнать, что это такое и как с этим бороться. В частности:

Is there a configuration option that should be used when building GCC to activate this macro by default, as suggested by this post? (I couldn't find any in the online documentation of the build process.) Is there really a relation between the nanosleep() function and the macro? The declaration of nanosleep() in ctime/time.h does not seem to depend on, or define, the macro. Is there any specific risk involved in defining the macro in my own header files, or as a -D option on the command line (as suggested in this related question)? What if I do this on a system where nanosleep() is not available, and how can I actually find out?

Update Начиная с GCC 4.8, поддержкаstd::this_thread::sleep_for() и тому подобное автоматически включается в libstdc ++. Флаг настройки больше не требуется. Отжурнал изменений GCC 4.8:

this_thread::sleep_for(), this_thread::sleep_until() and this_thread::yield() are defined without requiring the configure option --enable-libstdcxx-time;

Но обратите внимание на более подробную информацию об этом для GCC 4.8 и 4.9, приведенную в ответе Джонатана.

В любой моментconfigure проверитьnanosleep? Что это сказал? nneonneo
@nneonneo Я построил его, следуяbuild descriptions, не используя никаких специальных опций, кроме пользовательских каталогов. jogojapan
Пытатьсяconfigure --enable-libstdccxx-time как указано наgcc.gnu.org/bugzilla/show_bug.cgi?id=52680, Это, вероятно, было бы сделано сопровождающим библиотеки, но это не задокументированный флаг. nneonneo
@nneonneo Хороший вопрос. Я снова запустил конфигурацию (теперь с новой версией 4.7.2), но, к сожалению, в выводе сценария конфигурации нет упоминания о наносне (или что-либо еще, связанное с «сном» или «временем»). jogojapan
Вы сделали это сами или это C ++, поставляемый сопровождающим? nneonneo

Ваш Ответ

1   ответ
68

configure Скрипт проверяет вашу систему, чтобы увидеть, какие функции поддерживаются, и на основе результатов он определяет (или не определяет) различные макросы вc++config.h

В твоем случаеconfigure определили, что POSIXnanosleep() функция недоступна, а макрос не определен. Однако, как вы говорите,nanosleep() is доступно в вашей системе. Причина, по которой он не включенconfigure является то, что проверки для него даже не запускаются, если вы не используете--enable-libstdcxx-time вариант (задокументировано вConfiguration chapter of the libstdc++ manual, а не GCC настроить документы)

Is there a configuration option that should be used when building GCC to activate this macro by default, as suggested by this post? (I couldn't find any in the online documentation of the build process.)

Да,--enable-libstdcxx-time

Is there really a relation between the nanosleep() function and the macro? The declaration of nanosleep() in ctime/time.h does not seem to depend on, or define, the macro.

Объявление функции glibc не зависит от макроса libstdc ++, нет. Но макрос сообщает libstdc ++, использовать ли функцию или нет.

Is there any specific risk involved in defining the macro in my own header files, or as a -D option on the command line (as suggested in this related question)? What if I do this on a system where nanosleep() is not available, and how can I actually find out?

Это непослушно и не поддерживается, но будет работать. Макрос является внутренней деталью реализации, которая должна устанавливаться пользователем, а не пользователем, и изменение определения внутренних макросов реализации может привести к поломке. Но в этом случае это не произойдет, потому что единственный код, который зависит от него, находится в заголовке, никакой код библиотеки вlibstdc++.so подвергается воздействию.

Но было бы лучше переустановить GCC и использовать--enable-libstdcxx-time или, если это невозможно, отредактируйтеc++config.h определить макрос в true.

Если вы определите его в другой системе, гдеnanosleep() не доступно, вы получите ошибку компиляции, когда вы#include <thread>.

у меня есть немногоидеи для улучшения этой конфигурации, такnanosleep() а такжеsched_yield() будет проверяться по умолчанию, но у меня еще не было времени поработать над ними.

Update: Я совершил некоторые изменения, так что сборка 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 хоть.

Another update: GCC 4.9.0 вышел и теперь по умолчанию автоматически включаетnanosleep а такжеsched_yield на платформах, которые, как известно, поддерживают их. Больше нет необходимости использовать--enable-libstdcxx-time.

This is a great answer and deserves many upvotes. (Сейчас я перестраиваюсь с правильно написанным параметром и сообщу, когда он будет закончен, но в любом случае это объясняет фон, который меня интересовал.) jogojapan
Просто для подтверждения: после исправления орфографии опция сработала. Еще раз спасибо. jogojapan

Похожие вопросы