J'ai du code source compilé sous Windows. Je le convertis pour qu'il fonctionne sous Red Hat Linux.
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 quelques millisecondes. Cela ne fonctionnera pas sous Linux.
Cependant, je peux utiliser la fonction sleep(seconds)
, mais elle utilise un entier en secondes. Je ne veux pas convertir des millisecondes en secondes. Existe-t-il une fonction de veille alternative que je peux utiliser avec la compilation gcc sous Linux?
Oui - ancien POSIX normes définies usleep()
, donc disponible sous Linux:
int usleep(useconds_t usec);
LA DESCRIPTION
La fonction usleep () suspend l'exécution du thread appelant pendant (au moins) usec microsecondes. Le sommeil peut être légèrement prolongé par l’activité du système, par le temps passé à traiter l’appel ou par la granularité des temporisateurs système.
usleep()
prend microsecondes , vous devrez donc multiplier l'entrée par 1000 pour pouvoir dormir en millisecondes.
usleep()
a depuis été déconseillé puis supprimé de POSIX; pour le nouveau code, nanosleep()
est préféré:
#include <time.h> int nanosleep(const struct timespec *req, struct timespec *rem);
LA DESCRIPTION
nanosleep()
suspend l'exécution du thread appelant jusqu'à ce que soit au moins le temps spécifié dans*req
, soit 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 nanoseconde. Il est défini comme suit:
struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
Un exemple de fonction msleep()
implémentée à l'aide de nanosleep()
, poursuivant le sommeil s'il est interrompu par un signal:
int msleep(long msec)
{
struct timespec ts;
int res;
if (msec < 0)
{
errno = EINVAL;
return -1;
}
ts.tv_sec = msec / 1000;
ts.tv_nsec = (msec % 1000) * 1000000;
do {
res = nanosleep(&ts, &ts);
} while (res && errno == EINTR);
return res;
}
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
}
À la place de usleep()
, qui n'est pas définie dans POSIX 2008 (bien qu'elle ait été définie jusqu'à POSIX 2004, et qu'il est évidemment disponible sur les plates-formes Linux et autres avec un historique 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()
doit suspendre l'exécution du thread actuel jusqu'à l'expiration de l'intervalle de temps spécifié par l'argumentrqtp
ou jusqu'à ce qu'un signal soit envoyé au thread appelant et que son action consiste à appeler une fonction de capture de signal. ou pour terminer le processus. La durée de suspension peut être plus longue que celle demandée car la valeur de l'argument est arrondie à un multiple entier de la résolution de veille ou en raison de la planification d'une autre activité par le système. Toutefois, sauf en cas d'interruption d'un signal, le temps de suspension ne doit pas être inférieur au temps spécifié parrqtp
, 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.
Au-delà de utilisation , le modeste sélection avec des ensembles de descripteurs de fichier NULL vous permettra pause avec une précision microseconde, et sans risque de complications SIGALRM
.
sigtimedwait et sigwaitinfo offrent un comportement similaire.
#include <unistd.h>
int usleep(useconds_t useconds); //pass in microseconds