Mam kod źródłowy, który został skompilowany w systemie Windows. Konwertuję go, aby działał w systemie Red Hat Linux.
Kod źródłowy zawiera <windows.h>
plik nagłówkowy, a programista użył tej Sleep()
funkcji, aby czekać przez okres milisekund. To nie zadziała w systemie Linux.
Mogę jednak użyć tej sleep(seconds)
funkcji, ale używa ona liczby całkowitej w sekundach. Nie chcę zamieniać milisekund na sekundy. Czy istnieje alternatywna funkcja uśpienia, której mogę używać podczas kompilowania gcc w systemie Linux?
sleep(/*seconds*/)
w<unistd.h>
działa, ale jeśli używam zprintf("some things")
bez\n
, to nie działa.fflush(stdout);
po każdymprintf()
Odpowiedzi:
Tak - zdefiniowano starsze standardy POSIX
usleep()
, więc jest to dostępne w systemie Linux:usleep()
zajmuje mikrosekundy , więc będziesz musiał pomnożyć dane wejściowe przez 1000, aby spać w milisekundach.usleep()
od tego czasu jest przestarzały, a następnie usunięty z POSIX; dla nowego kodunanosleep()
preferowane:Przykładowa
msleep()
funkcja zaimplementowana wykorzystującananosleep()
kontynuację uśpienia w przypadku przerwania go sygnałem:#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; }
źródło
Możesz użyć tej funkcji międzyplatformowej:
#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 }
źródło
_POSIX_C_SOURCE >= 199309L
, jak w przypadku-ansi
lub-std=c89
, polecałbym użyćstruct timeval tv; tv.tv_sec = milliseconds / 1000; tv.tv_usec = milliseconds % 1000 * 1000; select(0, NULL, NULL, NULL, &tv);
zamiastusleep(milliseconds * 1000);
. Kredyt jest tutaj .nanosleep()
dokumentacja: man7.org/linux/man-pages/man2/nanosleep.2.html . Przydatne byłoby zamieszczenie linków do dokumentacji dla każdej użytej tutaj funkcji specyficznej dla platformy.gcc -Wall -g3 -std=c11 -o sleep_test sleep_test.c && ./sleep_test
na Linux Ubuntu z gcc w wersji 4.8.4, pojawia się następujące ostrzeżenie:warning: implicit declaration of function ‘usleep’ [-Wimplicit-function-declaration]
. Rozwiązaniem jest dodanie następujących 2 definicji na samej górze kodu: 1)#define __USE_POSIX199309
i 2)#define _POSIX_C_SOURCE 199309L
. Oba są wymagane, aby kod skompilował się bez żadnych ostrzeżeń (a także aby użyćnanoseconds()
funkcji, która jest dostępna).Alternatywnie do tego
usleep()
, co nie jest zdefiniowane w POSIX 2008 (chociaż zostało zdefiniowane do POSIX 2004 i jest ewidentnie dostępne na Linuksie i innych platformach z historią zgodności z POSIX), standard POSIX 2008 definiujenanosleep()
:źródło
Poza uśpieniem , skromny wybór z zestawami deskryptorów plików NULL pozwoli Ci zatrzymać się z mikrosekundową precyzją i bez ryzyka
SIGALRM
komplikacji.sigtimedwait i sigwaitinfo oferują podobne zachowanie.
źródło
#include <unistd.h> int usleep(useconds_t useconds); //pass in microseconds
źródło
#include <stdio.h> #include <stdlib.h> int main () { puts("Program Will Sleep For 2 Seconds"); system("sleep 2"); // works for linux systems return 0; }
źródło