Aplikacje Linux generalnie rozwidlają, a następnie wykonują (za pomocą execve ()), ale aplikacje Java i niektóre Apache MPM używają wątków. Jeśli rozwidlasz, używa fork + exec do odrodzenia procesu, jaka jest wersja wysokiego poziomu do wątkowania? W jaki sposób JVM lub Worker MPM spawnuje wątki?
9
Odpowiedzi:
Idea wątków i procesów jest mniej więcej taka sama: rozwidlasz ścieżkę wykonania. W przeciwnym razie wątki i procesy różnią się między innymi pamięcią. Tj. Procesy mają inną przestrzeń VM, a wątki współużytkują wszystko, co istniało przed podziałem.
Zarówno praca nad wątkami, jak i rozwidlanie za pomocą wywołania clone () (klon man 2):
Różnice wynikają z flag przekazywanych do clone (). Jak widać ze strony man, fork i threading to tylko zestaw predefiniowanych parametrów do klonowania (). Jednak można również robić z nim niestandardowe rzeczy.
źródło
Większość nie Unixowych wieloprocesorowych systemów operacyjnych (OS) używa wywołania „spawn ()” lub czegoś podobnego w celu wygenerowania nowego procesu lub przepływu kontrolnego systemu operacyjnego. Spawn () jest zwykle bardzo złożonym wywołaniem, z wieloma opcjami i dużym narzutem. Jedną z innowacji Uniksa było zapewnienie znacznie niższego ogólnego sposobu tworzenia procesów - fork (). Unix zadbał o wiele niezbędnych opcji spawn (), zezwalając na dowolne ilości przetwarzania przed drugą połową spawn () za pomocą exec ().
Ponieważ Unix i jego warianty były coraz częściej stosowane, okazało się, że użyteczne jest tworzenie niskiego narzutu, które było wykorzystywane. W rzeczywistości używano go tak bardzo, że ludzie chcieli jeszcze niższych ogólnych sposobów tworzenia procesów i tak narodził się pomysł „wątków”. Początkowo wątki były obsługiwane całkowicie przez proces inicjujący (a programy takie jak JVM mogą to robić z „zielonymi wątkami”); ale obsługa planowania wielowątkowego jest trudna i często była wykonywana niepoprawnie. Jest więc łatwiejszy, pośredni sposób wykonywania wątków, w którym system operacyjny obsługuje planowanie, ale narzut jest oszczędzany przez (zwykle) współdzielenie przestrzeni adresowej między wątkami.
Odpowiedź na twoje pytanie jest trudna, ponieważ istnieje kilka różnych, ale powiązanych ze sobą pojęć, które wszystkie są „wątkami”, a dla szczegółów potrzebujesz przymiotnika, aby opisać, do którego się odwołujesz. Z drugiej strony zrozumienie różnic prawdopodobnie doprowadzi cię do konkretnej odpowiedzi, jakiej chcesz. Wyszukaj takie rzeczy jak „lekkie procesy”, „wątki użytkownika” i „rfork ()”, aby uzyskać więcej informacji.
źródło
CreateProcess()
ale nic podobnego dofork()
.fork()
.Wątki i rozwidlenie to tak naprawdę dwie różne koncepcje, z których obie istnieją w systemach Unix / Linux (i obie mogą być używane w C / C ++).
Idea fork () jest (bardzo zasadniczo) stworzeniem osobnego procesu, który ma ten sam kod wykonania co proces nadrzędny i który rozpoczyna wykonywanie od linii rozwidlenia. Celem użycia widelców z funkcjami exec jest to, że funkcje exec zamykają proces, który je wywołał, kiedy się kończą. Tak więc zwykle rozwidlasz się, otrzymując PID każdego procesu (dziecko zawsze ma wartość 0) i każesz rodzicowi czekać, aż dziecko zakończy wykonywanie funkcji exec.
Wątki są używane do równoległości (pamiętaj, że rodzic czeka na dziecko, zwykle w rozwidlonym programie). Wątek, taki jak pthread w C / C ++ (wykonaj wyszukiwanie w Google), będzie działał równolegle z głównym procesem i może współdzielić zmienne globalne i funkcje globalne z oryginalnym programem. Ponieważ wątki Java zachowują się podobnie, wyobrażam sobie, że działają one bardziej jak te wątki niż proces rozwidlania.
Zasadniczo istnieje różnica między rozwidleniem a gwintowaniem. Robią wyraźnie różne rzeczy (choć wydają się podobne). Pojęcia te mogą być trudne do zrozumienia, ale możesz nauczyć się ich poprzez (obszerne) badania, jeśli masz szczerą chęć ich zrozumienia.
EDYCJA 1
Zapoznaj się z przykładami wywoływania i używania widelców i wątków. Zwróć uwagę na zachowanie funkcji exec i ich wpływ na główny program.
http://www.jdembrun.com:4352/computerScience/forkVSthread.zip
źródło
pthread
to API, a nie realizacja wątek.Zarówno JVM, jak i Apache MPM polegają na jądrze dla wątków natywnych. Oznacza to, że używają systemu operacyjnego do ich planowania. Oczywiście oba potrzebują własnego API do śledzenia rzeczy.
Stackoverflow ma już kilka pytań na ten temat:
Rodzime wątki JVM , sprawdź tę odpowiedź, aby uzyskać więcej szczegółów.
Apache ma dwa typy MPM: Prefork, z jednym procesem na wątek oraz Worker, który obsługuje wiele wątków: Apache MPM . Sprawdź odniesienie do
codebucket
źródło
Jest to specyficzne dla platformy, ale na Linuksie i przypuszczam, że wiele innych systemów zgodnych z POSIX używa lokalnej implementacji pthreads , interfejsu API wątkowości użytkownika. Na przykład:
Rozpoczyna nowe wywołanie wątku
somefunc
jako pierwszy punkt wykonania.Możesz także tworzyć wątki - różne od widelców, ponieważ współużytkują tę samą globalną przestrzeń pamięci sterty procesu nadrzędnego, zamiast uzyskiwać jej duplikat (ale pamiętaj, że każdy wątek wykonuje się z własną niezależną pamięcią stosu ) - z
clone()
wywołaniem systemowym, na którym zbudowane są pthreads.źródło