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/.