oracular (7) pipe.7.gz

Provided by: manpages-pl_4.23.1-1_all bug

NAZWA

       pipe - przegląd potoków i FIFO

OPIS

       Potoki i FIFO (zwane również potokami nazwanymi lub łączami nazwanymi) udostępniają jednokierunkowy kanał
       komunikacji międzyprocesowej. Potok ma koniec do odczytu oraz koniec do zapisu. Dane zapisane do końca do
       zapisu mogą być odczytane z końca do odczytu potoku.

       Potok  tworzy  się  za  pomocą  pipe(2),  które  tworzy nowy potok i zwraca dwa deskryptory plików, jeden
       odnoszący się do końca do odczytu potoku, a drugi odnoszący się do końca do zapisu. Potoków można użyć do
       utworzenia kanału komunikacji pomiędzy powiązanymi procesami; zob. pipe(2) aby zapoznać się z przykładem.

       FIFO  (skrót  od  ang.  First  In  First  Out – pierwszy na wejściu, pierwszy na wyjściu) posiada nazwę w
       systemie plików (utworzoną za pomocą mkfifo(3)) i jest otwierany przy użyciu open(2). Każdy  proces  może
       otworzyć FIFO, o ile uprawnienia pliku na to zezwalają. Koniec do odczytu otwiera się za pomocą znacznika
       O_RDONLY; koniec do zapisu, za pomocą O_WRONLY. Więcej szczegółów w podręczniku fifo(7). Uwaga: Choć FIFO
       mają  ścieżkę  w  systemie  plików,  to  wejście/wyjście  na  FIFO nie przeprowadza operacji na podległym
       urządzeniu (jeśli takie istnieje).

   Wejście/wyjście na potokach i FIFO
       Jedyna różnica pomiędzy potokami i FIFO polega na sposobie ich tworzenia i otwierania. Po ukończeniu tych
       zadań, wejście/wyjście na potokach i FIFO korzysta z dokładnie tej samej semantyki.

       Gdy  proces  spróbuje  odczytać z pustego potoku, read(2) zablokuje do momentu pojawienia się danych. Gdy
       proces spróbuje zapisać do  pełnego  potoku  (zob.  niżej),  write(2)  zablokuje  do  momentu  odczytania
       wystarczającej ilości danych z potoku, umożliwiającej poprawne przeprowadzenie zapisu.

       Nieblokujące  wejście/wyjście  można  uzyskać  za  pomocą  operacji  F_SETFL  fcntl(2),  w celu włączenia
       znacznika statusu otwartego pliku O_NONBLOCK lub otwierając fifo(7)  z  O_NONBLOCK.  Jeśli  jakiś  proces
       otworzy potok do zapisu, odczyt zawiedzie z błędem EAGAIN; w innych przypadkach, przy braku potencjalnych
       zapisujących, odczyt powiedzie się i powróci pusty.

       Kanał udostępniany przez potok jest strumienien bajtów: nie występuje koncept granic komunikatów.

       Jeśli wszystkie deskryptory pliku odnoszące się do końca do zapisu potoku  zostaną  zamknięte,  to  próba
       odczytu  za  pomocą  read(2)  z  potoku  przyniesie  koniec-pliku  (read(2)  zwróci  0).  Jeśli wszystkie
       deskryptory pliku odnoszące się do końca do odczytu  zostaną  zamknięte,  to  zapis  za  pomocą  write(2)
       spowoduje  wygenerowanie  sygnału SIGPIPE dla wywołującego procesu. Jeśli proces wywołujący zignoruje ten
       sygnał, to write(2) zawiedzie z błędem EPIPE. Aplikacje używające pipe(2) i fork(2) powinny  korzystać  z
       odpowiednich  wywołań  close(2), aby zamykać niepotrzebnie zduplikowane deskryptory pliku; to zapewni, że
       koniec-pliku i SIGPIPE/EPIPE są dostarczane tam, gdzie to konieczne.

       Do potoku nie da się zastosować lseek(2).

   Pojemność potoku
       Potok ma ograniczoną pojemność. Po zapełnieniu potoku, write(2) zablokuje lub zawiedzie, w zależności  od
       tego,  czy znacznik O_NONBLOCK jest ustawiony (zob. niżej). Różne implementacje posiadają odmienne limity
       pojemności potoku. Aplikacje nie powinny  zależeć  od  jakiejś  określonej  pojemności,  lecz  należy  je
       zaprojektować tak, aby konsumowały dane tak wcześnie jak to możliwe, w celu uniknięcia blokowania procesu
       zapisującego.

       Przed Linuksem 2.6.11, pojemność potoku była taka sama jak systemowy rozmiar strony (np. 4096  bajtów  na
       architekturze  i386). Od Linuksa 2.6.11, pojemność potoku wynosi 16 stron (tj. 65 536 bajtów w systemie o
       rozmiarze strony 4096 bajtów). Od Linuksa 2.6.35, domyślny rozmiar potoku wynosi 16 stron, ale  można  go
       odpytać  i  ustawić  za  pomocą  operacji  F_GETPIPE_SZ  i  F_SETPIPE_SZ  fcntl(2).  Więcej  szczegółów w
       podręczniku fcntl(2).

       Następująca operacja ioctl(2), którą można zastosować do deskryptora pliku, odnoszącego się do  dowolnego
       końca  potoku,  umieszcza  licznik  nieodczytanych  bajtów  w  potoku,  w  buforze int wskazanym ostatnim
       argumentem wywołania:

           ioctl(fd, FIONREAD, &nbytes);

       Operacja FIONREAD nie jest przewidziana żadnym standardem, ale udostępnia ją wiele implementacji.

   Pliki /proc
       W Linuksie, następujące pliki kontrolują wielkość pamięci, jaką można przeznaczyć potokom:

       /proc/sys/fs/pipe-max-pages (tylko w Linuksie 2.6.34)
              Górny limit pojemności, podany w  stronach,  jaką  nieuprzywilejowany  użytkownik  (nieposiadający
              przywileju (ang. capability) CAP_SYS_RESOURCE), może ustawić dla potoku.

              Domyślna  wartość  tego limitu to szesnastokrotność domyślnego rozmiaru potoku (zob. wyżej); dolny
              limit to dwie strony.

              Interfejs ten usunięto w Linuksie 2.6.35, na korzyść /proc/sys/fs/pipe-max-size.

       /proc/sys/fs/pipe-max-size (od Linuksa 2.6.35)
              Maksymalny rozmiar (w bajtach) poszczególnych potoków, jaki może być ustawiany przez  użytkowników
              bez  przywileju  CAP_SYS_RESOURCE. Wartość przypisana do tego pliku może być zaokrąglona w górę, w
              uwzględnieniu wartości użytej faktycznie,  ze  względu  na  wygodę  implementacji.  Aby  sprawdzić
              wartość zaokrągloną, należy wyświetlić wartość tego pliku, po przypisaniu mu wartości.

              Domyślną  wartością  pliku jest 1048576 (1 MiB). Minimalną wartością, jaką można przypisać do tego
              pliku, jest systemowy rozmiar strony. Próby ograniczenia limitu poniżej rozmiaru strony  spowodują
              niepowodzenie write(2) z błędem EINVAL.

              Od  Linuksa  4.9, wartość pliku działa również jako górny, domyślny limit pojemności nowego potoku
              lub nowo otwartego FIFO.

       /proc/sys/fs/pipe-user-pages-hard (od Linuksa 4.5)
              Bezwzględny limit całkowitego rozmiaru (w stronach) wszystkich potoków utworzonych lub ustawionych
              przez   pojedynczego   nieuprzywilejowanego   użytkownika   (tzn.   nieposiadającego   przywilejów
              CAP_SYS_RESOURCE ani CAP_SYS_ADMIN). Gdy całkowita liczba stron przypisanych do buforów potoku dla
              danego  użytkownika  osiągnie  tej  limit,  próby tworzenia nowych potoków będą odmawiane, a także
              próby zwiększenia rozmiaru potoku będą odmawiane.

              Gdy wartość limitu wynosi zero (tak jest domyślnie), bezwzględny limit nie obowiązuje.

       /proc/sys/fs/pipe-user-pages-soft (od Linuksa 4.5)
              Miękki limit całkowitego rozmiaru (w stronach)  wszystkich  potoków  utworzonych  lub  ustawionych
              przez   pojedynczego   nieuprzywilejowanego   użytkownika   (tzn.   nieposiadającego   przywilejów
              CAP_SYS_RESOURCE ani CAP_SYS_ADMIN). Gdy całkowita liczba stron przypisanych do buforów potoku dla
              danego  użytkownika  osiągnie  tej  limit,  poszczególne  potoki  tworzone  przez użytkownika będą
              ograniczone do jednej strony, a próby zwiększenia rozmiaru potoku będą odmawiane.

              Gdy wartość limitu wynosi zero, miękki limit nie obowiązuje. Domyślną wartością  tego  pliku  jest
              16384, co pozwala na tworzenie do 1024 potoków o domyślnym rozmiarze.

       Przed  Linuksem  4.9 pewne błędy wpływały na obsługę limitów pipe-user-pages-soft i pipe-user-pages-hard;
       zob. USTERKI.

   PIPE_BUF
       POSIX.1 określa, że zapis mniej niż PIPE_BUF bajtów musi być niepodzielny: dane wyjściowe  są  zapisywane
       do  potoku  jako  ciągła  sekwencja.  Zapis  więcej  niż  PIPE_BUF  nie musi być niepodzielny: jądro może
       przeplatać dane, z danymi zapisywanymi przez inne procesy. POSIX.1 wymaga, aby PIPE_BUF miał co  najmniej
       512  bajtów (w Linuksie PIPE_BUF ma 4096 bajtów). Dokładna semantyka zależy od tego, czy deskryptor pliku
       jest nieblokujący (O_NONBLOCK), czy występuje wiele zapisów  do  potoku  oraz  od  n,  liczby  bajtów  do
       zapisania:

       O_NONBLOCK wyłączone, n <= PIPE_BUF
              Wszystkie  n  bajtów  jest zapisane niepodzielnie; write(2) może zablokować, jeśli brak miejsca do
              natychmiastowego zapisu n bajtów

       O_NONBLOCK włączone, n <= PIPE_BUF
              Jeśli jest miejsce na zapisanie n  bajtów  do  potoku,  to  write(2)  natychmiast  powiedzie  się,
              zapisując wszystkie n bajtów; w przeciwnym wypadku write(2) zawodzi, z errno ustawionym na EAGAIN.

       O_NONBLOCK wyłączone, n > PIPE_BUF
              Zapis  jest  podzielny:  dane  przekazane  do  write(2)  mogą  ulec przepleceniu z write(2) innych
              procesów; write(2) blokuje do momentu zapisania n bajtów.

       O_NONBLOCK włączone, n > PIPE_BUF
              Gdy potok jest pełny, write(2) zawiedzie z errno  ustawionym  na  EAGAIN.  W  przeciwnym  wypadku,
              zapisanych  może  ulec od 1 do n bajtów (tzn. może wystąpić „częściowy zapis”, wywołujący powinien
              sprawdzić wartość zwróconą  przez  write(2),  aby  przekonać  się,  jak  wiele  bajtów  faktycznie
              zapisano), bajty te mogą być przeplatane z zapisami z innych procesów.

   Znaczniki statusu otwartego pliku
       Jedyne  znaczniki  statusu  otwartego  pliku,  jakie  można  sensownie  zastosować  do potoku lub FIFO to
       O_NONBLOCK i O_ASYNC.

       Ustawienie znacznika O_ASYNC na końcu do odczytu potoku powoduje wygenerowanie sygnału (domyślnie SIGIO),
       gdy  nowe  wejście  stanie  się  dostępne  na  potoku. Cel dostarczenia sygnałów należy ustawić za pomocą
       polecenia F_SETOWN fcntl(2). W Linuksie O_ASYNC jest obsługiwane w przypadku potoków i  FIFO  dopiero  od
       Linuksa 2.6.

   Uwagi dotyczące przenośności
       W  niektórych  systemach (ale nie w Linuksie), potoki są dwukierunkowe: dane mogą być transmitowane w obu
       kierunkach pomiędzy węzłami  końcowymi.  POSIX.1  wymaga  jedynie  potoków  jednokierunkowych.  Przenośne
       aplikacje powinny unikać polegania na semantyce potoków dwukierunkowych.

   USTERKI
       Przed   Linuksem   4.9   występowały   pewne  błędy  dotyczące  obsługi  limitów  pipe-user-pages-soft  i
       pipe-user-pages-hard przy używaniu operacji F_SETPIPE_SZ fcntl(2) do zmiany rozmiaru potoku:

       (a)  Przy zwiększaniu rozmiaru potoku, sprawdzenia dotyczące limitów miękkich i  bezwzględnych,  czynione
            były wobec istniejącej zajętości i z wyłączeniem pamięci wymaganej do zwiększenia pojemności potoku.
            Nowo powiększona pojemność potoku mogła wykroczyć (nawet znacznie)  poza  całkowitą  pamięć  używaną
            przez potoki użytkownika (mogło to również wyzwolić problem opisany jako następny).

            Od Linuksa 4.9, sprawdzenia limitów wliczają pamięć potrzebną do nowej pojemności potoku.

       (b)  Sprawdzenia limitów dokonywano nawet wówczas, gdy nowa pojemność potoków była niższa niż istniejąca.
            Mogło to prowadzić do problemów, gdy użytkownik ustawił znaczną pojemność potoku, a następnie limity
            ograniczono, co powodowało, że użytkownik nie mógł już zmniejszyć pojemności potoku.

            Od  Linuksa  4.9, sprawdzenia limitów następują tylko przy zwiększaniu pojemności potoku; użytkownik
            nieuprzywilejowany może zawsze zmniejszyć pojemność potoku.

       (c)  Wyliczanie i sprawdzanie limitów odbywało się w następujący sposób:

            (1)  Sprawdzenie, czy użytkownik przekroczył limit.
            (2)  Utworzenie nowego przydzielenia buforu potoku.
            (3)  Wyliczenie nowego przydzielenia wobec limitów.

            Była to sytuacja sprzyjająca hazardowi. Punkt (1) mogło przekroczyć jednocześnie wiele  procesów,  a
            przydzielone  następnie  bufory  potoku  były  wyliczane  jedynie w kroku (3), co mogło prowadzić do
            przekroczenia limitu przez przydzielony bufor potoku użytkownika.

            Od Linuksa 4.9, krok wyliczania jest dokonywany przed przydzieleniem, a operacja zawodzi, gdy  limit
            miałby być przekroczony.

       Przed  Linuksem  4.9,  błędy  podobne  do  opisanych  w  punktach (a) i (c) mogły występować również przy
       przydzielaniu przez jądro pamięci buforowi nowego potoku tj. przy wywoływaniu pipe(2) i  przy  otwieraniu
       uprzednio nieotwartego FIFO.

ZOBACZ TAKŻE

       mkfifo(1),  dup(2),  fcntl(2),  open(2),  pipe(2), poll(2), select(2), socketpair(2), splice(2), stat(2),
       tee(2), vmsplice(2), mkfifo(3), epoll(7), fifo(7)

TŁUMACZENIE

       Autorami polskiego tłumaczenia niniejszej strony podręcznika są: 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⟩.