44 votes

Qu'est-ce que _GLIBCXX_USE_NANOSLEEP ?

Une macro de préprocesseur appelée _GLIBCXX_USE_NANOSLEEP apparaît dans deux fichiers d'en-tête standard :

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

Dans une version par défaut de GCC 4.7.1 (Linux, 64 bits), la seule chose que l'on peut constater est que l'on n'a pas besoin d'utiliser le logiciel. c++config.h ce commentaire en inclut un autre :

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

Considérant que dans filetage la définition de std::this_thread::sleep_for() y std::this_thread::sleep_until() dépendent de la définition de la macro. Si elle n'est pas définie, les deux fonctions - bien que requises par la norme C++ - ne seront pas non plus définies.

Sur mon système (glibc 2.15), la macro n'est pas définie, bien que la commande nanosleep() (déclarée dans ctime ) existe et est opérationnel.

J'aimerais savoir de quoi il s'agit et comment y faire face. Plus précisément :

  • Existe-t-il une option de configuration qui devrait être utilisée lors de la construction de GCC pour activer cette macro par défaut, comme suggéré par ce poste ? (Je n'en ai pas trouvé dans le documentation en ligne du processus de construction .)
  • Y a-t-il vraiment une relation entre le nanosleep() et la macro ? La déclaration de nanosleep() en ctime / time.h ne semble pas dépendre de la macro, ni la définir.
  • Y a-t-il un risque particulier à définir la macro dans mes propres fichiers d'en-tête, ou en tant qu'une -D sur la ligne de commande (comme suggéré dans cette question connexe ) ? Et si je fais cela sur un système où nanosleep() n'est pas disponible, et comment puis-je le savoir ?

Mise à jour À partir de GCC 4.8, la prise en charge de l'option std::this_thread::sleep_for() et autres sont automatiquement inclus dans libstdc++. Aucun drapeau de configuration n'est plus nécessaire. Depuis le journal des modifications de GCC 4.8 :

this_thread::sleep_for(), this_thread::sleep_until() et this_thread::yield() sont définis sans nécessiter l'option de configuration --enable-libstdcxx-time ;

Mais notez les détails supplémentaires à ce sujet pour GCC 4.8 et 4.9 donnés dans la réponse de Jonathan.

70voto

Jonathan Wakely Points 45593

Lorsque la librairie libstdc++ est construite, son configure script teste votre système pour voir quelles fonctionnalités sont supportées, et sur la base des résultats, il définit (ou indéfinit) diverses macros dans le fichier c++config.h

Dans votre cas configure a déterminé que la norme POSIX nanosleep() n'est pas disponible et la macro n'est pas définie. Cependant, comme vous le dites, nanosleep() es disponible sur votre système. La raison pour laquelle il n'est pas activé par configure c'est que les vérifications ne sont même pas effectuées si vous n'utilisez pas l'option --enable-libstdcxx-time (documentée dans le Configuration chapitre du manuel libstdc++ (pas les documents de configuration de GCC)

  • Existe-t-il une option de configuration qui devrait être utilisée lors de la construction de GCC pour activer cette macro par défaut, comme le suggère ce post ? (Je n'en ai pas trouvé dans la documentation en ligne du processus de construction).

Oui, --enable-libstdcxx-time

  • Y a-t-il vraiment une relation entre la fonction nanosleep() et la macro ? La déclaration de nanosleep() dans ctime/time.h ne semble pas dépendre de la macro, ni la définir.

La déclaration de la fonction de la glibc ne dépend pas de la macro de libstdc++, non. Mais la macro indique à libstdc++ s'il faut utiliser la fonction ou non.

  • Y a-t-il un risque particulier à définir la macro dans mes propres fichiers d'en-tête, ou comme une option -D sur la ligne de commande (comme suggéré dans cette question connexe) ? Que se passe-t-il si je fais cela sur un système où nanosleep() n'est pas disponible, et comment puis-je le savoir ?

Elle est vilaine et n'est pas prise en charge, mais elle fonctionnera. La macro est un détail interne de l'implémentation qui doit être défini par configure et non par les utilisateurs et changer la définition des macros internes de l'implémentation peut casser des choses. Mais dans ce cas, ce n'est pas le cas car le seul code qui en dépend est dans un en-tête, aucun code de bibliothèque dans le fichier libstdc++.so est affecté.

Mais il serait préférable de réinstaller GCC et d'utiliser l'option --enable-libstdcxx-time ou, si cela n'est pas possible, modifiez votre fichier c++config.h pour définir la macro à true.

Si vous le définissez sur un système différent où nanosleep() n'est pas disponible, vous obtiendrez une erreur de compilation lorsque vous #include <thread> .

J'ai quelques idées pour améliorer cette configuration, donc nanosleep() y sched_yield() seront vérifiés par défaut, mais je n'ai pas encore eu le temps de travailler dessus.

Mise à jour : J'ai effectué quelques changements afin que la compilation de GCC 4.8 sans --enable-libstdcxx-time définira toujours std::this_thread::yield() (comme un no-op) et implémentera std::this_thread::sleep_for() y std::this_thread::sleep_until() en utilisant la résolution inférieure ::sleep() y ::usleep() au lieu de ::nanosleep() . Il est toujours préférable de définir --enable-libstdcxx-time cependant.

Une autre mise à jour : GCC 4.9.0 est sorti et active maintenant par défaut automatiquement nanosleep y sched_yield sur les plates-formes qui sont connues pour les supporter. Il n'est plus nécessaire d'utiliser --enable-libstdcxx-time .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X