Provided by: manpages-pl-dev_4.23.1-1_all bug

NAZWA

       nanosleep - usypia z wysoką rozdzielczością

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #include <time.h>

       int nanosleep(const struct timespec *duration,
                     struct timespec *_Nullable rem);

   Wymagane ustawienia makr biblioteki glibc (patrz feature_test_macros(7)):

       nanosleep():
           _POSIX_C_SOURCE >= 199309L

OPIS

       nanosleep()  zawiesza  wykonywanie wywołującego wątku, dopóki nie upłynie co najmniej czas
       podany w *duration albo dopóki nie zostanie dostarczony sygnał, który wyzwoli  przywołanie
       procedury obsługi w wątku wywołującym lub który zakończy proces.

       Jeśli  wywołanie  zostanie przerwane przez procedurę obsługi sygnału, nanosleep zwróci -1,
       ustawi errno na wartość EINTR i zapisze pozostały czas do do struktury  wskazywanej  przez
       rem,  o ile rem nie było równe NULL. Wartość *rem można wykorzystać do ponownego wywołania
       nanosleep() i dokończenia zadanej pauzy (jednak zob. UWAGI).

       Do podawania interwałów czasowych z dokładnością  nanosekundową,  używana  jest  struktura
       timespec(3).

       Wartość pola nanosekund musi być w zakresie [0, 999999999].

       W  porównaniu  ze  sleep(3)  i  usleep(3), nanosleep ma następujące zalety: oferuje wyższą
       rozdzielczość do określania czasu pauzy; POSIX.1 wyraźnie określa, że nie wpływają na  nie
       sygnały;  pozwala na łatwiejszą kontynuację uśpienia po przerwaniu przez procedurę obsługi
       sygnału.

WARTOŚĆ ZWRACANA

       Po udanym spauzowaniu na żądany czas, nanosleep()  zwróci  0.  Jeśli  wywołanie  przerwano
       przez procedurę obsługi sygnału lub wystąpi błąd, zwróci -1 i ustawi errno wskazując błąd.

BŁĘDY

       EFAULT Problem z kopiowaniem informacji z przestrzeni użytkownika.

       EINTR  Pauza  została przerwana sygnałem, dostarczonym wątkowi (zob. signal(7)). Pozostały
              czas uśpienia został zapisany do *rem,  więc  wątek  może  łatwo  wywołać  ponownie
              nanosleep() i dokończyć pauzę.

       EINVAL Wartość z pola tv_nsec nie była w zakresie [0, 999999999] lub tv_sec było ujemne.

WERSJE

       POSIX.1  określa,  że  nanosleep()  powinno  odmierzać  czas zegarem CLOCK_REALTIME (czasu
       rzeczywistego). Linux  dokonuje  tego  jednak  za  pomocą  zegara  CLOCK_MONOTONIC  (czasu
       monotonicznego).   Prawdopodobnie   nie   ma   to  znaczenia,  gdyż  norma  POSIX.1  wobec
       clock_settime(2)  podaje,  że  skoki  czasu  w  CLOCK_REALTIME  nie  powinny  wpływać   na
       nanosleep():

              Ustawienie  wartości  zegara  CLOCK_REALTIME za pomocą clock_settime(2) nie powinno
              mieć  wpływu  na  wątki,  które  są  zablokowane  w  oczekiwaniu  na  usługę  czasu
              względnego,  opartą  na tym zegarze, w tym funkcję nanosleep(); ... Te usługi czasu
              powinny zatem wygasać, gdy upłynie żądany okres, niezależnie od  nowej  lub  starej
              wartości zegara.

STANDARDY

       POSIX.1-2008.

HISTORIA

       POSIX.1-2001.

       Aby  wspierać  aplikacje  wymagające  znacznie  bardziej dokładnych pauz (np. aby sterować
       sprzętem o krytycznych zależnościach czasowych), nanosleep() radziło sobie z pauzami do  2
       milisekund  w  ten sposób, że oczekiwało z zajętością, z mikrosekundową precyzją, gdy było
       wywoływane przez  wątek,  działający  według  polityki  czasu  rzeczywistego,  takiej  jak
       SCHED_FIFO  czy  SCHED_RR.  To specjalnie rozszerzenie zostało usunięte w Linuksie 2.5.39,
       dlatego nie jest już dostępne od jądra Linux 2.6.0.

UWAGI

       Jeśli duration nie jest dokładnie  wielokrotnością  rozdzielczości  przedmiotowego  zegara
       (zob.  time(7),  to interwał ten zostanie zaokrąglony w górę, do następnej wielokrotności.
       Co więcej, po zakończenia pauzy, wciąż może wystąpić  zwłoka  przez  ponownym  zwolnieniem
       procesora w celu ponownego wykonania wątku wywołującego.

       Fakt, że nanosleep() pauzuje na interwał względny może być problematyczny, jeśli wywołanie
       jest ponownie restartowane po  otrzymaniu  sygnałów  przerwania,  ponieważ  czas  pomiędzy
       każdym  restartem i przerwaniem wywołania, spowoduje przesunięcie czasu, w jakim pauza się
       ostatecznie  zakończy.  Problemu  tego  można  uniknąć,  używając   clock_nanosleep(2)   z
       bezwzględną wartością czasu.

USTERKI

       Jeśli  program  przechwytujący sygnały i używający nanosleep() będzie otrzymywał sygnały z
       dużą częstością, to przydzielanie zasobów  powoduje  opóźnienia  i  błędy  zaokrąglenia  w
       obliczeniach,  dotyczących  interwału pauzy oraz zwracanej wartości remain, które dokonuje
       jądro, co oznacza, że wartość remain może systematycznie rosnąć  po  kolejnych  restartach
       wywołania   nanosleep().   Aby   uniknąć   tego   typu   problemów,   należy  korzystać  z
       clock_nanosleep(2) ze znacznikiem  TIMER_ABSTIME,  aby  pauzować  do  terminu  określonego
       bezwzględnie.

       W Linuksie 2.4, jeśli nanosleep() zostanie zatrzymane sygnałem (np. SIGTSTP), to wywołanie
       zawodzi z błędem EINTR po tym,  jak  wątek  zostanie  wznowiony  sygnałem  SIGCONT.  Jeśli
       wywołanie  systemowe  zostanie  później zrestartowane, to czas jaki wątek spędził w stanie
       zatrzymanym nie jest liczony do  czasu  pauzy.  Problem  naprawiono  w  Linuksie  2.6.0  i
       kolejnych jądrach.

ZOBACZ TAKŻE

       clock_nanosleep(2),  restart_syscall(2), sched_setscheduler(2), timer_create(2), sleep(3),
       timespec(3), usleep(3), time(7)

TŁUMACZENIE

       Autorami  polskiego  tłumaczenia  niniejszej  strony   podręcznika   są:   Przemek   Borys
       <pborys@dione.ids.pl>,  Andrzej  Krzysztofowicz <ankry@green.mf.pg.gda.pl> i Michał Kułach
       <michal.kulach@gmail.com>

       Niniejsze tłumaczenie jest wolną dokumentacją. Bliższe  informacje  o  warunkach  licencji
       można   uzyskać   zapoznając   się   z   GNU   General   Public   License   w   wersji   3
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩  lub  nowszej.  Nie   przyjmuje   się   ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy  w  tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres listy dyskusyjnej
       ⟨manpages-pl-list@lists.sourceforge.net⟩.