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

NAZWA

       fork - tworzy proces potomny

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

SKŁADNIA

       #include <unistd.h>

       pid_t fork(void);

OPIS

       fork()  tworzy  nowy  proces,  duplikując  proces  wywołujący.  Nowy  proces jest nazywany
       procesem potomnym (lub dzieckiem). Proces wywołujący jest nazywany  procesem  macierzystym
       (lub rodzicem).

       Proces  potomny  i  proces macierzysty działają w oddzielnych rejonach pamięci. W momencie
       wykonania fork()  oba  rejony  pamięci  mają  taką  samą  zawartość.  Zapisy  do  pamięci,
       przypisywania  (mmap(2))  i  odmapowywania  (munmap(2))  pliku  wykonane  wobec  jednego z
       procesów nie mają wpływu na drugi.

       Proces potomny jest dokładną  kopią  procesu  macierzystego  z  wyłączeniem  następujących
       punktów:

       •  Proces   potomny   ma  swój  unikatowy  identyfikator  procesu  i  nie  pasuje  ono  do
          identyfikatora żadnej istniejącej sesji lub grupy (setpgid(2)) procesu.

       •  Identyfikator  procesu  macierzystego  dla  procesu  potomnego  jest   taki   sam   jak
          identyfikator procesu macierzystego.

       •  Proces  potomny  nie dziedziczy blokad pamięci swojego procesu macierzystego (mlock(2),
          mlockall(2)).

       •  Użycie  zasobów  procesu  (getrusage(2))  i  liczniki  czasu  procesora  (times(2))  są
          resetowane do zera dla procesu potomnego.

       •  Zestaw   oczekujących   sygnałów   dla   procesu   potomnego   jest   początkowo  pusty
          (sigpending(2)).

       •  Proces potomny nie dziedziczy dostosowań semaforów od procesu macierzystego (semop(2)).

       •  Proces potomny nie dziedziczy blokad rekordów związanych z procesem od swojego  procesu
          macierzystego  (fcntl(2))  (z  drugiej  strony dziedziczy blokady opisu otwartego pliku
          (OFD) fcntl(2) oraz blokady flock(2) od swojego procesu macierzystego).

       •  Proces  potomny  nie  dziedziczy   czasomierzy   od   swojego   procesu   macierzystego
          (setitimer(2), alarm(2), timer_create(2)).

       •  Proces  potomny  nie dziedziczy zaległych, asynchronicznych operacji wejścia/wyjścia od
          procesu macierzystego (aio_read(3), aio_write(3)), ani nie dziedziczy żadnego kontekstu
          asynchronicznego wejścia/wyjścia od procesu macierzystego (zob. io_setup(2)).

       Atrybuty  procesu  w  powyższej liście są określone w normie POSIX.1. Proces macierzysty i
       potomny będą się  różnić  również  w  odniesieniu  do  następujących,  typowo  linuksowych
       atrybutów procesu:

       •  Proces  potomny  nie  odziedziczy  notyfikacji  o zmianie katalogu (dnotify) od swojego
          rodzica (więcej informacji w opisie F_NOTIFY w podręczniku fcntl(2)).

       •  Ustawienie PR_SET_PDEATHSIG prctl(2) jest resetowane, dzięki czemu proces  potomny  nie
          otrzyma sygnału, gdy jego proces macierzysty ulegnie zakończeniu.

       •  Domyślna  wartość  luzu czasomierza jest ustawiana na aktualną wartość luzu czasomierza
          procesu macierzystego. Więcej  informacji  w  opisie  PR_SET_TIMERSLACK  w  podręczniku
          prctl(2).

       •  Przypisania pamięci oznaczone znacznikiem MADV_DONTFORK madvise(2), nie są dziedziczone
          poprzez fork().

       •  Pamięć w przedziałach adresowych  oznaczonych  znacznikiem  MADV_WIPEONFORK  madvise(2)
          jest  zerowana  dla  procesu potomnego, po wykonaniu fork() (ustawienie MADV_WIPEONFORK
          nie ulega zmianie dla tych przedziałów adresowych, dla procesu potomnego).

       •  Sygnałem przerwania procesu potomnego jest zawsze SIGCHLD (zob. clone(2)).

       •  Bity uprawnień dostępu do portu ustawione za pomocą ioperm(2) nie są dziedziczone przez
          proces potomny; musi on sam włączyć wszystkie wymagane bity przy użyciu ioperm(2).

       Dalsze uwagi:

       •  Proces  potomny jest tworzony jednym wątkiem — tym który wywołał fork(). Cała wirtualna
          przestrzeń adresowa jest replikowana  dla  procesu  potomnego;  obejmuje  to  zatrzaski
          (muteksy),  zmienne warunkowe i inne obiekty pthread; podręcznik pthread_atfork(3) może
          okazać się przydatny w radzeniu sobie z problemami, jakie to może spowodować.

       •  W programie wielowątkowym, po fork() proces potomny może  bezpiecznie  wykonać  jedynie
          funkcje  które  są  async-signal-safe  (zob.  signal-safety(7))  aż do momentu, gdy nie
          wywoła execve(2).

       •  Proces potomny dziedziczy kopie zestawu deskryptorów otwartego pliku. Każdy  deskryptor
          pliku  procesu  potomnego  odnosi  się  do tego samego opisu otwartego pliku (OFD, zob.
          open(2)) jako deskryptor odpowiadającego pliku swego procesu macierzystego. Oznacza to,
          że  dwa  deskryptory pliku dzielą znaczniki statusu otwartego pliku, przesunięcia pliku
          oraz atrybuty wejście/wyjścia zasilane sygnałami  (zob.  opis  F_SETOWN  i  F_SETSIG  w
          fcntl(2)).

       •  Proces  potomny  dziedziczy  zestaw  deskryptorów  otwartej kolejki komunikatów procesu
          macierzystego (zob. mq_overview(7)). Każdy deskryptor w procesie potomnym odnosi się do
          tego  samego  opisu  kolejki  otwartego  komunikatu, jak odpowiadający deskryptor pliku
          procesu macierzystego. Oznacza to, że dwa deskryptory pliku dzielą  te  same  znaczniki
          (mq_flags).

       •  Proces  potomny kopiuje zestaw strumieni otwartego katalogu procesu macierzystego (zob.
          opendir(3)).   POSIX.1  wskazuje,  że  odpowiadające   strumienie   katalogów   procesu
          macierzystego   i   potomnego   mogą  dzielić  pozycjonowanie  strumienia  katalogu,  w
          Linuksie/glibc tak się nie dzieje.

WARTOŚĆ ZWRACANA

       Po pomyślnym zakończeniu, w procesie macierzystym zwracany jest PID procesu potomnego, a w
       procesie  potomnym  zwracane jest 0. Po błędzie zwracane jest -1 do procesu macierzystego,
       nie jest tworzony procesie potomny i odpowiednio ustawiane jest errno wskazując błąd.

BŁĘDY

       EAGAIN Napotkano nałożony systemowo limit liczby wątków. Występuje  wiele  limitów,  które
              mogą wyzwolić ten błąd:

              •  osiągnięto miękki limit zasobów RLIMIT_NPROC (ustawiany za pomocą setrlimit(2)),
                 który ogranicza  liczbę  procesów  i  wątków  dla  rzeczywistego  identyfikatora
                 użytkownika;

              •  osiągnięto    systemowy    limit    jądra    na   liczbę   procesów   i   wątków
                 /proc/sys/kernel/threads-max (zob. proc(5));

              •  osiągnięto maksymalną liczbę identyfikatorów  procesów  /proc/sys/kernel/pid_max
                 (zob. proc(5)); albo

              •  osiągnięto  limit  identyfikatorów  procesów (pids.max) nałożony przez kontroler
                 cgroup „liczba procesów” (PID-ów).

       EAGAIN Wywołanie działa według zasad  planisty  SCHED_DEADLINE  i  nie  posiada  znacznika
              zresetuj-przy-rozwidleniu. Zob. sched(7).

       ENOMEM fork()  nie potrafił zaalokować niezbędnych struktur jądra z powodu niedostatecznej
              ilości pamięci.

       ENOMEM Próbowano utworzyć proces potomny w przestrzeni  nazw  PID,  której  proces  „init”
              uległ zakończeniu. Zob. pid_namespaces(7).

       ENOSYS fork()   nie   jest  obsługiwane  na  tej  platformie  (np.  sprzęt  bez  jednostki
              Memory-Management Unit).

       ERESTARTNOINTR (od Linuksa 2.6.17)
              Wywołanie systemowe przerwano sygnałem i zostanie ono przeładowane (widać to  tylko
              przy śledzeniu).

WERSJE

   Różnice biblioteki C/jądra
       Od  glibc 2.3.3, zamiast przywoływać wywołanie systemowe jądra fork(), opakowanie fork() z
       biblioteki glibc, dostępne jako część implementacji wątkowania NPTL,  przywołuje  clone(2)
       ze  znacznikami,  zapewniającymi  taki  sam  efekt,  jak  tradycyjne  wywołanie  systemowe
       (wywołanie fork() jest równoważne wywołaniu clone(2) przy określeniu flags jako  wyłącznie
       SIGCHLD).  Opakowanie  z  biblioteki glibc przywołuje procedury obsługi rozwidlania, które
       ustanowiono za pomocą pthread_atfork(3).

STANDARDY

       POSIX.1-2008.

HISTORIA

       POSIX.1-2001, SVr4, 4.3BSD.

UWAGI

       Pod Linuksem fork() jest zaimplementowane za pomocą kopiowania stron pamięci przy zapisie,
       więc  jedynymi mankamentami są czas i pamięć wymagane do powielenia tablic stron rodzica i
       utworzenia unikalnej struktury zadania dla potomka.

PRZYKŁADY

       Zob. pipe(2) i wait(2), aby obejrzeć więcej przykładów.

       #include <signal.h>
       #include <stdint.h>
       #include <stdio.h>
       #include <stdlib.h>
       #include <sys/types.h>
       #include <unistd.h>

       int
       main(void)
       {
           pid_t pid;

           if (signal(SIGCHLD, SIG_IGN) == SIG_ERR) {
               perror("sygnał");
               exit(EXIT_FAILURE);
           }
           pid = fork();
           switch (pid) {
           case -1:
               perror("fork");
               exit(EXIT_FAILURE);
           case 0:
               puts("Proces potomny wychodzi.");
               exit(EXIT_SUCCESS);
           default:
               printf("Proces potomny ma PID %jd\n", (intmax_t) pid);
               puts("Proces macierzysty wychodzi.");
               exit(EXIT_SUCCESS);
           }
       }

ZOBACZ TAKŻE

       clone(2), execve(2), exit(2),  setrlimit(2),  unshare(2),  vfork(2),  wait(2),  daemon(3),
       pthread_atfork(3), capabilities(7), credentials(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⟩.