2009-07-21 3 views
82

J'ai un code source qui a été compilé sur Windows. Je suis en train de le convertir pour fonctionner sur Red Hat Linux.Existe-t-il une fonction de sommeil alternative en C en millisecondes?

Le code source a inclus le fichier d'en-tête <windows.h> et le programmeur a utilisé la fonction Sleep() pour attendre une période de millisecondes. Cela ne fonctionnera pas sur Linux.

Cependant, je peux utiliser la fonction sleep(seconds), mais cela utilise un nombre entier en secondes. Je ne veux pas convertir les millisecondes en secondes. Existe-t-il une autre fonction de sommeil que je peux utiliser avec la compilation de gcc sous Linux?

+0

'sommeil (/ * secondes * /)' dans '' fonctionne, mais si je l'utilise avec 'printf ("certaines choses") 'sans \ n', ce ne fonctionne pas. – EsmaeelE

+0

Pour l'utiliser dans ce cas, nous devons rincer la sortie avec 'fflush (stdout);' après chaque 'printf()' – EsmaeelE

Répondre

124

Oui - ancien POSIX normes définies usleep(), donc c'est disponible sur Linux:

int usleep(useconds_t usec); 

DESCRIPTION

La fonction usleep() suspend l'exécution du processus d'appel pour (au moins) microseconde usec. Le temps de veille peut être légèrement allongé par toute activité du système ou par le temps passé à traiter l'appel ou par la granularité des temporisateurs du système.

usleep() prend microsecondes, vous devrez multiplier l'entrée par 1000 pour dormir en millisecondes.


usleep() a depuis été dépréciée et par la suite retiré de Posix; pour le nouveau code, nanosleep() est préféré:

#include <time.h> 

    int nanosleep(const struct timespec *req, struct timespec *rem); 

DESCRIPTION

nanosleep() suspend l'exécution du thread appelant jusqu'à ce que au moins le temps spécifié dans *req est écoulée, ou la livraison d'un signal qui déclenche l'appel d'un gestionnaire dans le thread appelant ou qui termine le processus.

La structure timespec est utilisée pour spécifier des intervalles de temps avec une précision de l'ordre de la nanoseconde. Il est défini comme suit:

 struct timespec { 
      time_t tv_sec;  /* seconds */ 
      long tv_nsec;  /* nanoseconds */ 
     }; 
15

Au-delà usleep, l'select humble avec des ensembles de descripteurs de fichier NULL vous permettra de mettre en pause avec une précision microseconde, et sans risque de complications SIGALRM.

sigtimedwait and sigwaitinfo offrent un comportement similaire.

+0

Une astuce intelligente potentiellement utile ... – mickeyf

13
#include <unistd.h> 

int usleep(useconds_t useconds); //pass in microseconds 
26

Alternativement à usleep(), qui n'est pas défini dans POSIX 2008 (bien qu'il a été défini jusqu'en 2004 Posix, et il est évidemment disponible sur Linux et d'autres plates-formes avec une histoire de conformité POSIX), la norme Posix 2008 définit nanosleep():

nanosleep - sommeil haute résolution

#include <time.h> 
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp); 

La fonction nanosleep() fera en sorte que les Curren Le thread t doit être suspendu de l'exécution jusqu'à ce que l'intervalle de temps spécifié par l'argument rqtp soit écoulé ou qu'un signal soit envoyé au thread appelant, et son action consiste à invoquer une fonction de capture de signal ou à terminer le processus. Le temps de suspension peut être plus long que demandé car la valeur de l'argument est arrondie à un nombre entier entier de la résolution de sommeil ou à cause de la planification d'une autre activité par le système. Mais, sauf en cas d'interruption d'un signal, le temps de suspension ne doit pas être inférieur au temps spécifié par rqtp, mesuré par l'horloge système CLOCK_REALTIME.

L'utilisation de la fonction nanosleep() n'a aucun effet sur l'action ou le blocage d'un signal.

28

Vous pouvez utiliser cette fonction multi-plateforme:

#ifdef WIN32 
#include <windows.h> 
#elif _POSIX_C_SOURCE >= 199309L 
#include <time.h> // for nanosleep 
#else 
#include <unistd.h> // for usleep 
#endif 

void sleep_ms(int milliseconds) // cross-platform sleep function 
{ 
#ifdef WIN32 
    Sleep(milliseconds); 
#elif _POSIX_C_SOURCE >= 199309L 
    struct timespec ts; 
    ts.tv_sec = milliseconds/1000; 
    ts.tv_nsec = (milliseconds % 1000) * 1000000; 
    nanosleep(&ts, NULL); 
#else 
    usleep(milliseconds * 1000); 
#endif 
} 
+1

Lorsque nous n'avons pas '_POSIX_C_SOURCE> = 199309L', comme dans le cas de '-ansi' ou' -std = c89', je recommanderais d'utiliser 'struct timeval tv; tv.tv_sec = millisecondes/1000; tv.tv_usec = millisecondes% 1000 * 1000; select (0, NULL, NULL, NULL, &tv); 'au lieu de' usleep (millisecondes * 1000); '. Crédit va [ici] (http://stackoverflow.com/a/264378/5472899). –

Questions connexes