Linus Torvalds (torvalds@cs.helsinki.fi)
Wt, 6 sierpnia 1996 12:47:31 +0300 (EET DST)
Wiadomości posortowane według: [data] [wątek] [temat] [autor]
Następna wiadomość: Bernd P. Ziller: „Re: Ups w get_hash_table”
Poprzednia wiadomość: Linus Torvalds: „Re: Zamawianie żądań we / wy”
W poniedziałek, 5 sierpnia 1996 r. Peter P. Eiserloh napisał:
Musimy zachować jasną koncepcję wątków. Zbyt wielu ludzi myli wątek z procesem. Poniższa dyskusja nie odzwierciedla obecnego stanu linuksa, ale jest raczej próbą pozostania na dyskusji na wysokim poziomie.
NIE!
Nie ma powodu, aby sądzić, że „wątki” i „procesy” są odrębnymi bytami. Tak to się tradycyjnie robi, ale osobiście uważam, że myślenie w ten sposób jest poważnym błędem. Jedynym powodem, aby myśleć w ten sposób, jest bagaż historyczny.
Zarówno wątki, jak i procesy to tak naprawdę tylko jedna rzecz: „kontekst wykonania”. Próba sztucznego rozróżnienia różnych przypadków jest po prostu samoograniczająca.
„Kontekst wykonania”, zwany niniejszym COE, jest tylko zlepkiem całego stanu tego COE. Ten stan obejmuje takie rzeczy, jak stan procesora (rejestry itp.), Stan MMU (odwzorowania stron), stan uprawnień (uid, gid) i różne „stany komunikacji” (otwarte pliki, procedury obsługi sygnałów itp.). Tradycyjnie różnica między „wątkiem” a „procesem” polegała głównie na tym, że wątki mają stan procesora (+ prawdopodobnie jakiś inny stan minimalny), podczas gdy cały inny kontekst pochodzi z procesu. Jest to jednak tylko
jeden sposób na podzielenie całkowitego stanu COE i nic nie wskazuje na to, aby był to właściwy sposób. Ograniczanie się do tego rodzaju obrazu jest po prostu głupie.
Sposób Linux myśli na ten temat (i sposób chcę rzeczy do pracy) jest to, że nie ma czegoś takiego jak „proces” lub „nici”. Istnieje tylko suma COE (nazywana przez Linux „zadaniem”). Różni COE mogą współdzielić ze sobą części swojego kontekstu, a jednym podzbiorem tego współdzielenia jest tradycyjna konfiguracja „wątku” / „procesu”, ale tak naprawdę należy to postrzegać TYLKO jako podzbiór (jest to ważny podzbiór, ale znaczenie to przychodzi nie z projektu, ale ze standardów: oczywiście chcemy uruchamiać programy wątkowe zgodne ze standardami również na Linuksie).
W skrócie: NIE projektuj wokół sposobu myślenia w wątku / procesie. Jądro powinno być zaprojektowane w oparciu o sposób myślenia COE, a następnie biblioteka pthreads może eksportować ograniczony interfejs pthreads do użytkowników, którzy chcą korzystać z tego sposobu patrzenia na COE.
Tylko jako przykład tego, co staje się możliwe, gdy myślisz o COE w przeciwieństwie do wątku / procesu:
- Możesz zrobić zewnętrzny program „cd”, co jest tradycyjnie niemożliwe w UNIX i / lub proces / wątek (głupi przykład, ale pomysł jest taki, że możesz mieć tego rodzaju „moduły”, które nie są ograniczone do tradycyjnego UNIXa / konfiguracja wątków). Wykonaj:
klon (CLONE_VM | CLONE_FS);
child: execve („external-cd”);
/ * „execve ()” rozdzieli maszynę wirtualną, więc jedynym powodem, dla którego użyliśmy CLONE_VM, było przyspieszenie procesu klonowania * /
- Możesz zrobić "vfork ()" w naturalny sposób (obsługuje minimalną obsługę jądra, ale ta obsługa idealnie pasuje do sposobu myślenia CUA):
klon (CLONE_VM);
child: kontynuuj uruchamianie, ewentualnie execve ()
matka: poczekaj na wykonanie
- możesz wykonać zewnętrzne „diamony we / wy”:
klon (CLONE_FILES);
dziecko: otwórz deskryptory pliku itp
matka: użyj fd's dziecko otwarte i vv.
Wszystkie powyższe prace działają, ponieważ nie jesteś przywiązany do sposobu myślenia w wątku / procesie. Pomyślmy na przykład o serwerze WWW, w którym skrypty CGI są wykonywane jako „wątki wykonania”. Nie możesz tego zrobić z tradycyjnymi wątkami, ponieważ tradycyjne wątki zawsze muszą współużytkować całą przestrzeń adresową, więc musisz połączyć wszystko, co kiedykolwiek chciałeś zrobić na samym serwerze internetowym („wątek” nie może zostać uruchomiony inny plik wykonywalny).
Myśląc o tym jako o „kontekście realizacji” problemu zamiast Twoje zadania mogą teraz wybrał do realizacji programów zewnętrznych (= oddzielić przestrzeń adresową od rodzica) etc, czy chcą, czy mogą one na przykład wszystkiego zakładowego z rodzicem , z wyjątkiem dla deskryptory plików (aby pod-„wątki” mogły otwierać wiele plików bez potrzeby, aby rodzic musiał się nimi martwić: zamykają się automatycznie po wyjściu pod-„wątku” i nie zużywają plików fd w rodzicu) .
Pomyśl na przykład o wątku „inetd”. Chcesz niskiego narzutu fork + exec, więc w systemie Linux zamiast zamiast „fork ()” piszesz inetd wielowątkowy, w którym każdy wątek jest tworzony za pomocą CLONE_VM (współdziel przestrzeń adresową, ale nie udostępniaj pliku deskryptory itp.). Następnie dziecko może wykonać, jeśli była to usługa zewnętrzna (na przykład rlogind), a może była to jedna z wewnętrznych usług inetd (echo, timeofday), w którym to przypadku po prostu robi to i wychodzi.
Nie możesz tego zrobić za pomocą „wątku” / „procesu”.
Linus