2009-07-21 27 views
82

Tengo un código fuente compilado en Windows. Lo estoy convirtiendo para ejecutar en Red Hat Linux.¿Existe una función de suspensión alternativa en C a milisegundos?

El código fuente ha incluido el archivo de encabezado <windows.h> y el programador ha utilizado la función Sleep() para esperar un período de milisegundos. Esto no funcionará en Linux.

Sin embargo, puedo usar la función sleep(seconds), pero eso usa números enteros en segundos. No quiero convertir milisegundos en segundos. ¿Hay alguna función de suspensión alternativa que pueda usar con la compilación de gcc en Linux?

+0

'sueño (/ * segundos * /)' en '' funciona, pero si yo uso con 'printf ("algunas cosas") 'sin' \ n', no funciona. – EsmaeelE

+0

Para usar en este caso, debemos enjuagar la salida con 'fflush (stdout);' después de cada 'printf()' – EsmaeelE

Respuesta

124

Sí - mayor POSIX estándares definidos usleep(), por lo que esto está disponible en Linux:

int usleep(useconds_t usec); 

DESCRIPCIÓN

función

El usleep() suspende la ejecución del proceso de llamada para (por lo menos) usec microsegundos. La suspensión se puede alargar ligeramente por cualquier actividad del sistema o por el tiempo dedicado al procesamiento de la llamada o por la granularidad de los temporizadores del sistema .

usleep() toma microsegundos, por lo que tendrá que multiplicar la entrada en 1000 con el fin de dormir en milisegundos.


usleep() desde ha dejado de utilizarse y posteriormente retirado de POSIX; para un código nuevo, se prefiere nanosleep():

#include <time.h> 

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

DESCRIPCIÓN

nanosleep() suspende la ejecución del subproceso de la llamada hasta que al menos haya transcurrido el tiempo especificado en *req, 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 */ 
     }; 
15

Más allá usleep, el humilde select con conjuntos de descriptores de archivo nulo le permitirá hacer una pausa con una precisión de microsegundos, y sin el riesgo de complicaciones SIGALRM.

sigtimedwait and sigwaitinfo ofrecen comportamientos similares.

+0

Un truco inteligente potencialmente útil ... – mickeyf

13
#include <unistd.h> 

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

Como alternativa a usleep(), que no se define en POSIX 2008 (aunque se definió hasta POSIX de 2004, y es, evidentemente, disponible en Linux y otras plataformas con un historial de cumplimiento POSIX), el POSIX estándar 2008 define nanosleep():

nanosleep - alta resolución del sueño

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

La función nanosleep() hará que los Curren t El hilo se suspenderá de la ejecución hasta que haya transcurrido el intervalo de tiempo especificado por el argumento rqtp o se haya entregado una señal al hilo de llamada, y su acción sea invocar una función de captura de señal o terminar el proceso. El tiempo de suspensión puede ser más largo que el solicitado porque 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, excepto en el caso de ser interrumpido por una señal, el tiempo de suspensión no debe ser inferior al tiempo especificado por rqtp, medido por el reloj del sistema CLOCK_REALTIME.

El uso de la función nanosleep() no tiene efecto sobre la acción o el bloqueo de cualquier señal.

28

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 
    usleep(milliseconds * 1000); 
#endif 
} 
+1

Cuando no tenemos '_POSIX_C_SOURCE> = 199309L', como en el caso de '-ansi' o' -std = c89', recomendaría usar 'struct timeval tv; tv.tv_sec = milisegundos/1000; tv.tv_usec = milisegundos% 1000 * 1000; select (0, NULL, NULL, NULL, &tv); 'en lugar de' usleep (milisegundos * 1000); '. El crédito va [aquí] (http://stackoverflow.com/a/264378/5472899). –

Cuestiones relacionadas