¿Existe una función de suspensión alternativa en C a milisegundos?

6 minutos de lectura

avatar de usuario
hormiga2009

Tengo un código fuente que fue compilado en Windows. Lo estoy convirtiendo para que se ejecute en Red Hat Linux.

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

Sin embargo, puedo usar el sleep(seconds) función, pero que utiliza enteros en segundos. No quiero convertir milisegundos a segundos. ¿Existe una función de suspensión alternativa que pueda usar con la compilación gcc en Linux?

  • sleep(/*seconds*/) en <unistd.h> funciona, pero si lo uso con printf("some things") sin \nno funciona.

    – EsmaeelE

    26 de noviembre de 2017 a las 13:33

  • Para usar en este caso, debemos vaciar la salida con fflush(stdout); después de cada printf()

    – EsmaeelE

    26 de noviembre de 2017 a las 13:47

avatar de usuario
coste y flete

si – mayor POSIX estándares definidos 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 microsegundospor 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 el nuevo código, 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;
}

  • ¿Por qué siguen desaprobando funciones simples para funciones complicadas? En lugar de romperte el cerebro con nanosegundos (), también podrías usar usleep por el momento.

    usuario9599745

    6 de junio de 2019 a las 9:02

  • usleep no puede hacer nanosegundos mientras que nanosleep debería

    –Anton Krug

    26 de agosto de 2020 a las 17:48

  • @AntonKrug En muchos entornos, incluso la precisión de microsegundos no se puede lograr de manera realista.

    –Erich Kitzmüller

    28 de diciembre de 2020 a las 13:17


  • @ErichKitzmueller Los entornos integrados y sin sistema operativo pueden alcanzar ~50 ns. Y depende de cómo se implementaron HAL y las bibliotecas. Por ejemplo, puede invocar fopen en objetivos que ni siquiera tienen un sistema de archivos (para enviar caracteres a UART). Y llame a printf en dispositivos que no tienen pantallas. Y, sin embargo, a menudo el código es totalmente portátil entre hosts x86 y objetivos integrados.

    –Anton Krug

    29 de diciembre de 2020 a las 1:46

avatar de usuario
bernardo ramos

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
}

  • cuando no tenemos _POSIX_C_SOURCE >= 199309Lcomo en el caso de -ansi o -std=c89recomendaría usar struct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = milliseconds % 1000 * 1000; select(0, NULL, NULL, NULL, &tv); en lugar de usleep(milliseconds * 1000);. El crédito va aquí.

    – Josh Sanford

    29 de septiembre de 2016 a las 18:18


  • ¡Gran respuesta! Nota, aquí está el nanosleep() documentación: man7.org/linux/man-pages/man2/nanosleep.2.html. Sería útil publicar los enlaces de documentación para cada función específica de la plataforma utilizada aquí.

    – Gabriel grapas

    26 de abril de 2019 a las 2:23

  • También tenga en cuenta que al compilar con gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test en Linux Ubuntu, con gcc versión 4.8.4, recibo la siguiente advertencia: warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]. La solución es agregue las siguientes 2 definiciones en la parte superior de su código: 1) #define __USE_POSIX199309 y 2) #define _POSIX_C_SOURCE 199309L. Ambas cosas son necesarios para que el código se compile sin ninguna advertencia (y también para usar el nanoseconds() función, que tiene disponible).

    – Gabriel grapas

    26 de abril de 2019 a las 2:44


  • Respuesta relacionada que acabo de hacer: stackoverflow.com/a/55860234/4561887

    – Gabriel grapas

    26 de abril de 2019 a las 3:02

avatar de usuario
jonathan leffler

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 cumplimiento de 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);

los nanosleep() hará que el subproceso actual se suspenda de la ejecución hasta el intervalo de tiempo especificado por el 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 podrá ser inferior al tiempo señalado por rqtpmedido por el reloj del sistema CLOCK_REALTIME.

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

Más allá de tu duermeel humilde Seleccione con conjuntos de descriptores de archivo NULL le permitirán pausar con precisión de microsegundos y sin el riesgo de SIGALRM complicaciones

sigtimedwait y sigwaitinfo ofrecer un comportamiento similar.

#include <unistd.h>

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

avatar de usuario
Odín

#include <stdio.h>
#include <stdlib.h>
int main () {

puts("Program Will Sleep For 2 Seconds");

system("sleep 2");      // works for linux systems


return 0;
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad