NAZWA¶
clone - utworzenie procesu potomnego
SKŁADNIA¶
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
int flags, void *arg);
_syscall2(int, clone, int, flags, void *,
child_stack)
OPIS¶
Uwaga! To tłumaczenie może być nieaktualne!
clone tworzy nowy proces, podobnie jak
fork(2).
clone jest
funkcją biblioteczną posadowioną na wierzchu
niższego wywołania funkcji systemowej
clone, do
której w dalszym ciągu będziemy się odnosić
jako do
sys_clone. Opis
sys_clone jest podany pod koniec
niniejszej strony.
W odróżnieniu od
fork(2), funkcje te pozwalają
procesom potomnym współdzielić części ich
kontekstu wykonania, takie jak obszar pamięci, tablica
deskryptorów plików czy tablica programów obsługi
sygnałów, z procesem wywołującym. (Należy
zauważyć, że na tej stronie podręcznika
"proces wywołujący" normalnie odnosi się do
"procesu macierzystego". Zobacz opis
CLONE_PARENT
poniżej.)
clone służy głównie do implementacji
wątków: zarządzanie wieloma wątkami programu,
które działają równolegle we
współdzielonym obszarze pamięci.
Gdy za pomocą
clone tworzony jest proces potomny, uruchamia on
aplikację funkcyjną
fn(
arg). (Różni
się to od
fork(2), gdzie proces potomny kontynuuje wykonanie od
miejsca wywołania
fork(2).) Argument
fn jest
wskaźnikiem do funkcji, która jest wywoływana przez
proces potomny na początku jego działania. Argument
arg
jest przekazywany do funkcji
fn.
Gdy aplikacja funkcyjna
fn(
arg) powróci, proces potomny
kończy działanie. Liczba całkowita zwrócona przez
fn jest kodem zakończenia procesu potomnego. Proces potomny
może również zakończyć się jawnie
wołając
exit(2) lub po otrzymaniu krytycznego
sygnału.
Argument
child_stack określa położenie stosu
używanego przez proces potomny. Ponieważ potomek i proces
wywołujący mogą współdzielić
pamięć, nie jest możliwe, aby proces potomny
korzystał z tego samego stosu, co proces wywołujący.
Proces wywołujący musi więc przydzielić obszar
pamięci przeznaczony na stos potomka i przekazać wskaźnik
do tego obszaru w
clone. Stosy rosną w dół na
wszystkich procesorach, na których działa Linux (z
wyjątkiem procesorów HP PA), więc
child_stack
zazwyczaj wskazuje na najwyższy adres obszaru pamięci
zarezerwowanego na stos potomka.
Niższy bajt
flags zawiera numer sygnału wysyłanego
do rodzica, gdy proces potomny ginie. Jeśli określono inny
sygnał niż
SIGCHLD, to proces macierzysty musi
podać opcję
__WALL lub
__WCLONE czekając na
potmka w
wait(2). Gdy sygnał nie zostanie określony, to
proces macierzysty nie zostanie zawiadomiony o zakończeniu pracy
potomka.
flags może również być bitowym OR jednej lub
kilku następujących stałych określających,
co będzie współdzielone pomiędzy procesem
wywołującym a procesem potomnym:
- CLONE_PARENT
- (od Linuksa 2.4 w górę) Jeśli CLONE_PARENT
będzie ustawione, to rodzic nowego procesu potomnego
(zwrócony przez getppid(2)) będzie ten sam, co dla
procesu wywołującego.
Jeśli CLONE_PARENT nie zostanie ustawione, to (jak dla
fork(2)) rodzicem potomka będzie proces
wywołujący.
Należy zauważyć, że to proces macierzysty,
zwracany przez getppid(2), zostanie powiadomiony o
zakończeniu pracy przez potomka, więc jeśli
CLONE_PARENT będzie ustawione, to zawiadomiony zostanie
rodzic procesu wywołującego, a nie sam proces
wywołujący
- CLONE_FS
- Jeśli ustawione będzie CLONE_FS, to
wywołujący i proces potomny będą
współdzielić informacje o systemie plików.
Informacje te obejmują katalog główny systemu
plików, bieżący katalog roboczy i umaskę.
Dowolne z wywołań chroot(2), chdir(2) lub
umask(2) wykonane przez proces wywołujący lub proces
potomny będzie obowiązywać również w
drugim procesie.
Jeśli CLONE_FS nie zostanie ustawione, to proces potomny
będzie pracować na kopii informacji o systemie plików
procesu wywołującego z chwili wywołania clone.
Wywołania chroot(2), chdir(2), umask(2)
wykonane później przez jeden z procesów nie
będą mieć wpływu na drugi proces.
- CLONE_FILES
- Jeśli CLONE_FILES będzie ustawione, to proces
wywołujący i procesy potomne będą
współdzielić tablicę deskryptorów
plików. Deskryptory plików zawsze będą
dotyczyć tych samych plików w procesie
wywołującym i w procesach potomnych. Dowolny deskryptor
pliku utworzony przez proces wywołujący, jak też
przez proces potomny będzie obowiązywać
również w drugim procesie. Podobnie, jeśli jeden z
procesów zamknie deskryptor pliku lub zmieni stowarzyszone z nim
znaczniki, będzie to obowiązywać
również w drugim procesie.
If CLONE_FILES nie zostanie ustawione, to proces potomny odziedziczy
kopię wszystkich deskryptorów plików otwartych w
procesie macierzystym w chwili wywołania clone. Operacje na
deskryptorach plików przeprowadzone później przez
proces wywołujący lub przez proces potomny nie
będą miały wpływu na drugi proces.
- CLONE_NEWNS
- (począwszy od Linuksa 2.4.19) Uruchamianie procesu potomnego w
nowej przestrzeni nazw.
Każdy proces istnieje w jakiejś przestrzeni nazw.
przestrzeń nazw procesu są to dane (zbiór
montowań) opisujące hierarchię plików
widzianą przez proces. Po fork(2) lub clone(2), gdy
nie ustawiono znacznika CLONE_NEWNS, potomek żyje w tej
samej przestrzeni nazw, co rodzic. Funkcje systemowe mount(2) i
umount(2) zmieniają przestrzeń nazw procesu
wywołującego, a zatem także innych procesów
żyjących w tej samej przestrzeni nazw, lecz nie mają
wpływu na procesy w innej przestrzeni nazw.
Po clone(2), gdy ustawiono znacznik CLONE_NEWNS, sklonowany
potomek jest uruchamiany w nowej przestrzeni nazw, inicjowanej jako kopia
przestrzeni nazw rodzica.
Znacznik CLONE_NEWNS może zostać podany jedynie przez
proces uprzywilejowany. Zabronione jest podanie w tym samym
wywołaniu clone zarówno CLONE_NEWNS, jak i
CLONE_FS.
- CLONE_SIGHAND
- Jeśli CLONE_SIGHAND będzie ustawione, to proces
wywołujący i procesy potomne będą
współdzielić tablicę programów
obsługi sygnałów. Jeśli proces
wywołujący lub proces potomny wywoła
sigaction(2), aby zmienić zachowanie towarzyszące
sygnałowi, zachowanie to zostanie zmienione również w
drugim procesie. Jednakże, proces wywołujący i proces
potomny wciąż będą posiadać osobne
maski sygnałów i zestawy sygnałów
oczekujących. Zatem jeden z nich może zablokować lub
odblokować niektóre sygnały za pomocą
sigprocmask(2) nie wpływajac na drugi proces.
Jeśli CLONE_SIGHAND nie zostanie ustawione, to proces potomny
odziedziczy kopię programów obsługi
sygnałów od procesu wywołującego z chwili
uruchomienia clone. Wywołania sigaction(2)
przeprowadzone później przez jeden z procesów nie
będą mieć wpływu na drugi proces.
- CLONE_PTRACE
- Jeśli zostanie podane CLONE_PTRACE, a proces
wywołujący będzie śledzony, to
śledzenie obejmie również potomka (zobacz
ptrace(2)).
- CLONE_VFORK
- Jeśli CLONE_VFORK będzie ustawione, wykonywanie
procesu wywołującego zostanie wstrzymane do chwili, gdy
potomek zwolni swoją pamięć wirtualną za
pomocą execve(2) lub _exit(2) (jak przy
vfork(2)).
Jeśli CLONE_VFORK nie zostanie ustawione, wtedy zarówno
proces wywołujący, jak i potomny podlegają po
wywołaniu clone szeregowaniu zadań i aplikacja nie
może zakładać, że ich wykonywanie
będzie się odbywać w określonej
kolejności.
- CLONE_VM
- Jeśli CLONE_VM będzie ustawione, to proces
wywołujący i potomny będą
działać w tym samym obszarze pamięci. W
szczególności, zapisy do pamięci wykonywane przez
proces wywołujący lub przez proces potomny
będą widoczne dla drugiego z procesów. Ponadto,
dowolne mapowania pamięci i usunięcia mapowań
wykonane przez jeden z tych procesów za pomocą
mmap(2) lub munmap(2) będą dotyczyć
również drugiego procesu.
Jeśli CLONE_VM nie zostanie ustawione, to proces potomny
będzie działać w kopii obszaru pamięci procesu
wywołującego, wykonanej w chwili wywołania
clone. Zapisy do pamięci oraz mapowania i usunięcia
mapowań wykonane przez jeden z tych procesów nie
będą dotyczyć drugiego z nich, tak jak w przypadku
fork(2).
- CLONE_PID
- Jeśli CLONE_PID będzie ustawione, to proces potomny
będzie tworzony z tym samym ID procesu, jaki ma proces
wywołujący.
Jeśli CLONE_PID nie zostanie ustawione, to proces potomny
będzie mieć unikalny ID procesu, inny niż ID procesu
wywołującego.
Ten znacznik może być podany tylko przez proces
uruchamiający system (PID 0).
- CLONE_THREAD
- (Począwszy od Linuksa 2.4) Jeśli CLONE_THREAD
będzie ustawione, to potomek będzie umieszczony w tej samej
grupie wątków, do której należy proces
wywołujący.
Jeśli CLONE_THREAD nie zostanie ustawione, to potomek
będzie umieszczony w swojej własnej (nowej) grupie
wątków, której ID jest taki sam, jak ID procesu.
(Grupy wątków zostały dodane w Linuksie 2.4 dla
obsługiwać wątki POSIX-owe dla zbioru procesów
współdzielących ten sam PID. W Linuksie 2.4
wywołania funkcji getpid(2) zwracają ID grupy
wątków procesu wywołującego.)
Funkcja systemowa
sys_clone odpowiada w sposób bardziej
zbliżony funkcji
fork(2), w której wykonanie procesu
potomnego jest kontynuowane od miejsca wywołania. Zatem,
sys_clone wymaga jedynie argumentów
flags i
child_stack, które mają znaczenie takie samo, jak dla
clone. (Należy zauważyć, że
kolejność tych argumentów jest inna aniżeli dla
clone.)
Inna różnicą w przypadku
sys_clone jest to,
że argument
child_stack może być zerem. W tym
przypadku, semantyka "kopiowania podczas zapisu" gwarantuje,
że proces potomny otrzyma osobną kopię stosu, gdy
którykolwiek z procesów zmodyfikuje stos. W tym przypadku aby
funkcja działała prawidłowo, nie należy
podawać opcji
CLONE_VM.
WARTOŚĆ ZWRACANA¶
Po pomyślnym zakończeniu, w wątku rodzica zwracany jest PID
potomka. W wypadku błędu, w kontekście procesu
wywołującego zwracane jest -1, a proces potomny nie jest
tworzony i odpowiednio ustawiane jest
errno .
BŁĘDY¶
- EAGAIN
- Działa już zbyt wiele procesów.
- ENOMEM
- Za mało pamięci aby przydzielić struktuę
zadania dla procesu potomnego, lub aby skopiować niezbędne
fragmenty kontekstu procesu wywołującego.
- EINVAL
- Zwracane przez clone, gdy podano dla child_stack
wartość zerową.
- EINVAL
- W flags podano jednocześnie CLONE_FS i
CLONE_NEWNS.
- EINVAL
- Podano CLONE_THREAD a nie podano CLONE_SIGHAND.
(Począwszy od Linuksa 2.5.35.)
- EPERM
- CLONE_PID zostało podane przez proces o niezerowym PID.
USTERKI¶
Dla wersji jądra 2.1.97 nie należy używać znacznika
CLONE_PID, gdyż inne części jądra i
większość oprogramowania systemowego wcąż
zakłada, że identyfikatory procesów są unikalne.
Brak wpisu dla
clone w wersji 5 biblioteki libc. libc 6 (inaczej, glibc
2) udostępnia
clone zgodnie z opisem na niniejszej stronie
podręcznika.
UWAGI¶
Dla wersji jądra 2.4.7-2.4.18 znacznik CLONE_THREAD wymuszał
znacznik CLONE_PARENT.
ZGODNE Z¶
Funkcje
clone i
sys_clone są specyficzne dla Linuksa i nie
powinny być używane w programach przenośnych.
Pisząc programy aplikacji wielowątkowych (wiele
wątków zarządzających tym samym obszarem
pamięci), lepiej używać biblioteki wspomagającej
wielowątkowe API zgodne z POSIX 1003.1c, takiej jak biblioteka
LinuxThreads (zawarta w glibc2). Zobacz
pthread_create(3).
Ta strona podręcznika dotyczy jąder 2.0.x, 2.1.x, 2.2.x, 2.4.x,
oraz glibc 2.0.x i 2.1.x.
ZOBACZ TAKŻE¶
fork(2) wait(2),
pthread_create(3)
Powyższe tłumaczenie pochodzi z nieistniejącego już
Projektu Tłumaczenia Manuali i
może nie być
aktualne. W razie zauważenia różnic między
powyższym opisem a rzeczywistym zachowaniem opisywanego programu lub
funkcji, prosimy o zapoznanie się z oryginalną
(angielską) wersją strony podręcznika za pomocą
polecenia:
- man --locale=C 2 clone
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
znaleźć pod adresem
http://sourceforge.net/projects/manpages-pl/.