2012-09-21 21 views
42

Una macro preprocessore chiamato _GLIBCXX_USE_NANOSLEEP appare in due file di intestazione standard:Che cosa è _GLIBCXX_USE_NANOSLEEP?

  • C++/4.7.1/x86_64-unknown-linux-gnu/bit/C++ config.h
  • C++/4.7.1/filo

In un accumulo di default di GCC 4.7.1 (Linux, 64-bit) l'unica cosa C++ config.h include è questo commento:

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

considerando filo, la definizione di std::this_thread::sleep_for() e std::this_thread::sleep_until() dipendono dalla macro da definire. Se non è definito, entrambe le funzioni –, sebbene richieste dallo standard C++ –, non saranno definite neanche.

Sul mio sistema (glibc 2.15), la macro non è definita, anche se la funzione nanosleep() (dichiarata in ctime) esiste ed è operativa.

Mi piacerebbe sapere di cosa si tratta e come gestirlo. In particolare:

  • Esiste un'opzione di configurazione che dovrebbe essere utilizzato quando si costruisce GCC per attivare questa macro per impostazione predefinita, come suggerito da this post? (Non sono riuscito a trovarne nello online documentation of the build process.)
  • Esiste davvero una relazione tra la funzione nanosleep() e la macro? La dichiarazione di nanosleep() in ctime/time.h non sembra dipendere o definire la macro.
  • Esiste qualche rischio specifico nella definizione della macro nei miei file di intestazione o come opzione -D nella riga di comando (come suggerito in this related question)? Cosa succede se lo faccio su un sistema in cui nanosleep() non è disponibile e come posso effettivamente scoprirlo?

aggiornamento Da GCC 4.8 in poi, il supporto per std::this_thread::sleep_for() e simili è automaticamente incluso nella libstdC++. Non è più richiesto alcun flag di configurazione. Da the GCC 4.8 change log:

this_thread :: sleep_for(), this_thread :: sleep_until() e this_thread :: resa() sono definite senza richiedere l'opzione di configurazione --enable-libstdcxx-tempo;

Ma si noti gli ulteriori dettagli su questo per GCC 4.8 e 4.9 dato nella risposta di Jonathan.

+0

Lo hai creato da solo o è un C++ fornito dal manutentore? – nneonneo

+0

@nneonneo L'ho creato seguendo le [build descriptions] (http://gcc.gnu.org/install/), senza usare opzioni speciali ad eccezione delle directory specifiche dell'utente. – jogojapan

+1

In qualsiasi momento, 'configure' verifica la presenza di' nanosleep'? Che cosa diceva? – nneonneo

risposta

68

Quando libstdC++ è costruito il suo script di configure mette alla prova il vostro sistema per vedere quali funzioni sono supportate, e sulla base dei risultati che definisce (o non-definisce) diverse macro in c++config.h

Nel tuo caso configure stabilito che la funzione POSIX nanosleep() non è disponibile e la macro non è definita. Tuttavia, come dici tu, nanosleep()è disponibile sul tuo sistema.Il motivo per cui non è abilitato di configure è che i controlli per esso non hanno nemmeno correre a meno che non si utilizza l'opzione --enable-libstdcxx-time (documentato nel Configuration chapter of the libstdc++ manual, non la documentazione di GCC configure)

  • Esiste un'opzione di configurazione che dovrebbe essere usato quando si crea GCC per attivare questa macro di default, come suggerito da questo post? (Non ho trovato alcuna nella documentazione in linea del processo di generazione.)

Sì, --enable-libstdcxx-time

  • C'è davvero una relazione tra la funzione nanosleep() e la macro? La dichiarazione di nanosleep() in ctime/time.h non sembra dipendere o definire la macro.

La dichiarazione della funzione di glibc non dipende da libstdc 's ++ macro, no. Ma la macro dice a libstdC++ se usare o meno la funzione.

  • C'è qualche rischio specifico coinvolto nella definizione della macro nei miei file di intestazione, o come opzione -D sulla riga di comando (come suggerito in questa domanda correlate)? Cosa succede se lo faccio su un sistema in cui nanosleep() non è disponibile e come posso effettivamente scoprirlo?

E 'cattivo e non è supportato, ma funzionerà. La macro è un dettaglio di implementazione interno che dovrebbe essere impostato da configure e non dagli utenti e la modifica della definizione delle macro interne dell'implementazione può rompere le cose. Ma in questo caso non lo farà perché l'unico codice che dipende da esso è in un'intestazione, nessun codice di libreria in libstdc++.so è interessato.

Ma sarebbe meglio reinstallare GCC e utilizzare l'opzione --enable-libstdcxx-time oppure, se ciò non è possibile, modificare il valore c++config.h per definire la macro su true.

Se lo si definisce su un sistema diverso in cui nanosleep() non è disponibile, verrà visualizzato un errore di compilazione quando si utilizza #include <thread>.

Ho qualche ideas per migliorare quella configurazione, quindi nanosleep() e sched_yield() verranno controllati per impostazione predefinita, ma non ho ancora avuto il tempo di lavorarci sopra.

Aggiornamento: ho commesso alcune modifiche in modo che la costruzione di GCC 4.8 senza --enable-libstdcxx-time sarà ancora definire std::this_thread::yield() (come un no-op) e realizzerà std::this_thread::sleep_for() e std::this_thread::sleep_until() utilizzando la risoluzione più bassa ::sleep() e ::usleep() funzioni invece di ::nanosleep(). È comunque meglio definire --enable-libstdcxx-time.

altro aggiornamento: GCC 4.9.0 è fuori e ora predefiniti per consentire automaticamente nanosleep e sched_yield su piattaforme che sono noti per sostenerli.Non è più necessario utilizzare --enable-libstdcxx-time.

+3

** Questa è un'ottima risposta e merita molti voti. ** (Sto ricostruendo ora con l'opzione corretta e riferirò una volta che è finito, ma in ogni caso, questo spiega lo sfondo a cui ero interessato.) – jogojapan

+0

Solo per confermare: dopo aver corretto l'ortografia dell'opzione, ha funzionato. Grazie ancora. – jogojapan