Linux używa modelu wątków 1-1, bez (do jądra) bez rozróżnienia między procesami i wątkami - wszystko jest po prostu zadaniem wykonalnym. *
W Linuksie wywołanie systemowe clone
klonuje zadanie z konfigurowalnym poziomem udostępniania, między innymi:
CLONE_FILES
: udostępnij tę samą tabelę deskryptorów plików (zamiast tworzyć kopię)
CLONE_PARENT
: nie konfiguruj relacji rodzic-dziecko między nowym zadaniem a starym (w przeciwnym razie child getppid()
= rodzic getpid()
)
CLONE_VM
: udostępnij to samo miejsce w pamięci (zamiast tworzyć kopię COW )
fork()
Połączenia clone(
najmniej dzielą się, )
a pthread_create()
połączenia clone(
dzielą najwięcej )
. **
fork
ing kosztuje nieco więcej niż pthread_create
ing z powodu kopiowania tabel i tworzenia mapowań COW dla pamięci, ale programiści jądra Linuksa próbowali (i udało się) zminimalizować te koszty.
Przełączanie między zadaniami, jeśli współużytkują tę samą przestrzeń pamięci i różne tabele, będzie nieco tańsze niż w przypadku, gdy nie zostaną one udostępnione, ponieważ dane mogą być już załadowane do pamięci podręcznej. Jednak przełączanie zadań jest nadal bardzo szybkie, nawet jeśli nic nie jest współużytkowane - jest to coś, co programiści jądra Linuksa starają się zapewnić (i zapewnić to).
W rzeczywistości, jeśli jesteś w systemie multi-procesora, nie dzielenie może faktycznie być korzystne dla wydajności: jeśli każde zadanie jest uruchomiony na innym procesorze, synchronizacja pamięci współdzielonej jest drogie.
* Uproszczony. CLONE_THREAD
powoduje, że dostarczanie sygnałów jest współużytkowane (co wymaga CLONE_SIGHAND
, co dzieli tabelę obsługi sygnałów).
** Uproszczony. Istnieją zarówno SYS_fork
i SYS_clone
wywołań systemowych, ale w jądrze, sys_fork
i sys_clone
są bardzo cienkie obwolut wokół tej samej do_fork
funkcji, która sama jest cienka otoki wokół copy_process
. Tak, terminy process
, thread
i task
są używane zamiennie raczej w jądrze Linuksa ...