Макрос препроцессора с именем _GLIBCXX_USE_NANOSLEEP появляется в двух стандартных заголовочных файлах:
В стандартной сборке GCC 4.7.1 (Linux, 64-bit) единственное C ++ config.h включает в себя этот комментарий:
/* Defined if nanosleep is available. */
/* #undef _GLIBCXX_USE_NANOSLEEP */
Тогда как в нить, определение 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, поддержка 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, приведенную в ответе Джонатана.
Когда libstdc ++ собран configure
Скрипт проверяет вашу систему, чтобы увидеть, какие функции поддерживаются, и на основе результатов он определяет (или не определяет) различные макросы в c++config.h
В твоем случае configure
определили, что POSIX nanosleep()
функция недоступна, а макрос не определен. Однако, как вы говорите, nanosleep()
является доступно в вашей системе. Причина, по которой он не включен configure
является то, что проверки для него даже не запускаются, если вы не используете --enable-libstdcxx-time
вариант (задокументировано в конфигурация глава руководства по libstdc ++, не GCC настроить документы)
- Есть ли параметр конфигурации, который следует использовать при сборке GCC для активации этого макроса по умолчанию, как предлагается в этом посте? (Я не смог найти ничего в онлайн-документации процесса сборки.)
Да, --enable-libstdcxx-time
- Действительно ли существует связь между функцией nanosleep () и макросом? Объявление nanosleep () в ctime / time.h, похоже, не зависит от макроса и не определяет его.
Объявление функции 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
,
Других решений пока нет …