Alternativamente a usleep()
, que no está definido en POSIX 2008 (aunque se definió hasta POSIX 2004 y evidentemente está disponible en Linux y otras plataformas con un historial de conformidad con POSIX), el estándar POSIX 2008 define nanosleep()
:
nanosleep
- sueño de alta resolución
#include <time.h>
int nanosleep(const struct timespec *rqtp, struct timespec *rmtp);
El nanosleep()
hará que la ejecución del subproceso actual se suspenda hasta el intervalo de tiempo especificado por rqtp
ha transcurrido el argumento o se envía una señal al subproceso de llamada, y su acción es invocar una función de captura de señal o terminar el proceso. El tiempo de suspensión puede ser mayor que el solicitado debido a que el valor del argumento se redondea a un múltiplo entero de la resolución de suspensión o debido a la programación de otra actividad por parte del sistema. Pero, salvo el caso de ser interrumpido por una señal, el tiempo de suspensión no será inferior al tiempo señalado por rqtp
, medido por el reloj del sistema CLOCK_REALTIME.
El uso del nanosleep()
La función no tiene efecto sobre la acción o el bloqueo de ninguna señal.
Sí:se definieron estándares POSIX más antiguos usleep()
, por lo que está disponible en Linux:
int usleep(useconds_t usec);
DESCRIPCIÓN
La función usleep() suspende la ejecución del subproceso de llamada durante (al menos) microsegundos usec. La suspensión puede alargarse ligeramente por cualquier actividad del sistema o por el tiempo empleado en procesar la llamada o por la granularidad de los temporizadores del sistema.
usleep()
toma microsegundos , por lo que tendrás que multiplicar la entrada por 1000 para poder dormir en milisegundos.
usleep()
desde entonces ha quedado obsoleto y posteriormente eliminado de POSIX; para código nuevo, nanosleep()
se prefiere:
#include <time.h> int nanosleep(const struct timespec *req, struct timespec *rem);
DESCRIPCIÓN
nanosleep()
suspende la ejecución del subproceso de llamada hasta al menos el tiempo especificado en*req
ha transcurrido, o la entrega de una señal que desencadena la invocación de un controlador en el subproceso de llamada o que finaliza el proceso.La estructura timespec se utiliza para especificar intervalos de tiempo con precisión de nanosegundos. Se define de la siguiente manera:
struct timespec { time_t tv_sec; /* seconds */ long tv_nsec; /* nanoseconds */ };
Un ejemplo msleep()
función implementada usando nanosleep()
, continuando el sueño si es interrumpido por una señal:
#include <time.h>
#include <errno.h>
/* msleep(): Sleep for the requested number of milliseconds. */
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;
}
Puede utilizar esta función multiplataforma:
#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
if (milliseconds >= 1000)
sleep(milliseconds / 1000);
usleep((milliseconds % 1000) * 1000);
#endif
}