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-inconnu-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 c ++ config.h inclut est ce commentaire:

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

Alors que dans thread , la définition de std::this_thread::sleep_for() et std::this_thread::sleep_until() dépend de la macro à définir. S’il n’est pas défini, les deux fonctions – bien que requirejses par le standard 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 fonction nanosleep() (déclarée dans ctime ) existe et soit opérationnelle.

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

  • Existe-t-il une option de configuration à utiliser lors de la création de GCC pour activer cette macro par défaut, comme suggéré dans cet article ? (Je n’ai pas pu en trouver dans la documentation en ligne du processus de construction .)
  • 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 ni définir la macro.
  • Existe-t-il un risque spécifique lié à la définition de la macro dans mes propres fichiers d’en-tête ou en tant qu’option -D sur la ligne de commande (comme suggéré dans cette question associée )? Que faire si je le fais sur un système où nanosleep() n’est pas disponible et comment puis-je le savoir?

Mise à jour À partir de GCC 4.8, le support de std::this_thread::sleep_for() et similaires est automatiquement inclus dans libstdc ++. Aucun indicateur de configuration n’est requirejs. À partir du journal des modifications 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.

Lorsque libstdc ++ est construit, son script configure teste votre système pour voir quelles fonctionnalités sont sockets en charge, et en fonction des résultats, il définit (ou non) diverses macros dans c++config.h

Dans votre cas, configure déterminé que la fonction POSIX nanosleep() n’est pas disponible et que la macro n’est pas définie. Cependant, comme vous le dites, nanosleep() est disponible sur votre système. La raison pour laquelle il n’est pas activé par configure est que les contrôles ne sont même pas exécutés à moins que vous n’utilisiez l’option --enable-libstdcxx-time (documentée dans le chapitre Configuration du manuel libstdc ++ , pas dans les documents de configuration GCC).

  • Existe-t-il une option de configuration à utiliser lors de la création de GCC pour activer cette macro par défaut, comme suggéré dans cet article? (Je n’ai pas pu en trouver 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 ni définir la macro.

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

  • Existe-t-il un risque spécifique lié à la définition de la macro dans mes propres fichiers d’en-tête ou en tant qu’option -D sur la ligne de commande (comme suggéré dans cette question associée)? Que faire si je le fais sur un système où nanosleep () n’est pas disponible et comment puis-je le savoir?

C’est vilain et non supporté, mais ça va marcher. La macro est un détail d’implémentation interne qui doit être défini par configure et non par les utilisateurs et la modification de la définition des macros internes de l’implémentation peut casser des choses. Mais dans ce cas, ce ne sera pas le cas car le seul code qui en dépend est dans un en-tête, aucun code de bibliothèque dans libstdc++.so n’est affecté.

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

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

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

Mise à jour: J’ai commis des modifications pour que la construction de GCC 4.8 sans --enable-libstdcxx-time définisse toujours std::this_thread::yield() (comme un no-op) et implémentera std::this_thread::sleep_for() et std::this_thread::sleep_until() utilisant les fonctions lower resolution ::sleep() et ::usleep() au lieu de ::nanosleep() . Il est cependant préférable de définir --enable-libstdcxx-time .

Une autre mise à jour: GCC 4.9.0 est sortie et nanosleep désormais par défaut automatiquement nanosleep et sched_yield sur les plates-formes connues pour les prendre en charge. Il n’est plus nécessaire d’utiliser --enable-libstdcxx-time .