Jak działa spanie w wątku?

15

Kiedy śpisz na wątku, co się właściwie dzieje?

Widzę, że uśpienie wątku „wstrzymuje bieżący wątek na określony czas” . Ale jak to działa?

Zgodnie z tym, jak Thread.sleep () działa wewnętrznie i jak naprawdę działa Thread.sleep? :

  • czas trwania snu będzie podlegał pewnej szczegółowości specyficznej dla systemu
  • sen blokuje
  • wątek opuszcza procesor i zatrzymuje jego wykonywanie
  • wątek nie zużywa czasu procesora podczas snu

Po prostu nie do końca rozumiem wewnętrzną i podstawową mechanikę tego, co to wszystko znaczy.

Rozumiem, że istnieje coś o nazwie harmonogram, który jest odpowiedzialny za przełączanie między wątkami.

Źródła wydają się wskazywać, że różni się to w zależności od systemu operacyjnego (lub sprzętu?), A większość wątków ma około 1–60 ms na wykonanie pewnych działań, zanim procesor przełączy się na inny wątek.

Ale kiedy wątek śpi (na przykład wiele sekund), jak go wznawia? Zgaduję, że w jakiś sposób zaangażowany jest zegar, czy to zegar płyty głównej? Czy ma to związek z częstotliwością taktowania procesora?

A nawet jeśli zaangażowany jest licznik czasu, skąd procesor wie, kiedy nadszedł czas, aby ponownie zwrócić uwagę na wątek? Czy nie musiałby stale sprawdzać wątku, aby sprawdzić, czy jest gotowy? Czy to nie jest efektywne odpytywanie i dlatego zajmuje trochę czasu procesora?

Czy uśpienie wątku jest specyficzne dla języka, czy system operacyjny jest za to odpowiedzialny, czy jest to coś specyficznego dla procesora?

Czy ktoś mógłby mi to wyjaśnić za pomocą podstawowych wyjaśnień na temat harmonogramu i tego, co robi procesor przez cały czas?

Rowan Freeman
źródło
2
Przebudzenie uśpionego wątku ponownie działa w oparciu o przerwania czasowe, zwykle generowane przez zegar przerwania, który jest komponentem sprzętowym niezależnym od podstawowej części procesora przetwarzającej instrukcje. Pozwala to uniknąć potrzeby odpytywania. Być może to wyjaśnienie Quory wyjaśni niektóre rzeczy: quora.com/How-does-threading-work-at-CPU-level
Doc Brown
1
Większość maszyn JVM faktycznie nie implementuje wielowątkowości: wszystko, co robią, to korzysta z możliwości wielowątkowości podstawowego systemu operacyjnego. Jeśli naprawdę chcesz wiedzieć, jak to działa, istnieje wiele książek na temat projektowania systemu operacyjnego.
Solomon Slow

Odpowiedzi:

11

Uruchomienie programu wymaga znacznie więcej niż tylko kodu w tym programie.

Każdy program działający w systemie wieloprocesowym znajduje się pod kontrolą harmonogramu systemu operacyjnego , a program planujący utrzymuje jawną tabelę z informacją o tym, który proces jest uruchomiony, które czekają na uruchomienie, gdy dostępne są cykle procesora, a które nawet nie są próbuje biec (śpi). Program planujący zwykle przypisuje do procesów odcinki czasu o równej wielkości w zależności od ich priorytetu i historii ich wykonania. Ostatecznie ta pętla jest napędzana przerwaniami sprzętowymi, zwykle generowanymi przez oscylator na płycie głównej.

Uśpienie jest zawsze funkcją obsługiwaną przez język programowania, ponieważ obsługuje go środowisko wykonawcze, w którym zostanie wykonane. Zwykły program nie może zawiesić się , może tylko powiedzieć harmonogramu, jak to lubi być traktowana - i planista jest w żaden sposób zobowiązana lub nawet zawsze możliwość zaspokojenia tego życzenia. Pomyśl o zamknięciu laptopa i przejściu w stan hibernacji; oscylator płyty głównej wciąż pulsuje, ale ponieważ program planujący nie działa, żaden proces nie może być uruchomiony bez względu na to, jak wysoki jest jego priorytet.

Kilian Foth
źródło
Dotyczy to (generalnie) procesów, ale nie zawsze prawdy w wątkach, które czasem zależą od języka. Wątki mogą być implementowane niezależnie od systemu operacyjnego i mogą być kooperatywne lub zapobiegawcze. Na przykład Ruby ma „włókna” (oprócz nici). Włókna rubinowe są ustalane wspólnie.
david25272,
To prawda, że ​​tylko natywne wątki działają w ten sposób. Zielone wątki są planowane przez maszynę wirtualną wykonującą program w języku skompilowanym bajtowo. Zwykle są używane, gdy natywne wątki nie są dostępne lub gdy uruchamiany jest kod, który nie jest odpowiednio bezpieczny dla wątków (maszyna wirtualna może czasami zapewnić, że semantyka programu wielowątkowego pozostanie poprawna w sposób, którego nie może zaplanować system operacyjny).
Kilian Foth,
7

Jak wspomniał Doc Brown w komentarzu, przerwania są kluczem, nie tylko do spania.

Przerwanie jest sprzętowym sygnałem, że procesor powinien przerwać to, co robi, i uruchomić kawałek kodu. Zewnętrzne urządzenia wyzwalają przerwania, gdy wymagają uwagi procesora: na przykład, gdy dysk zakończył odczyt danych, naciśnięto klawisz lub licznik na płycie głównej osiągnął zero.

Kod obsługi przerwań jest na ogół bardzo mały i bardzo szybki. Na przykład, gdy dysk wskazuje, że blok został skopiowany do pamięci, system operacyjny może po prostu zapisać ten fakt na liście „gotowych bloków”, a następnie powrócić do wszystkiego, co robił. Nie chcesz, aby procesor spędzał cały swój czas na kodzie obsługi przerwań i nie uruchamiał kodu użytkownika.

Jeden kawałek przerwania napędzane kodu, który nie jest koniecznie małe jest harmonogram. Jest on wyzwalany sygnałem odliczającego czas i bada stan systemu za każdym razem, gdy jest uruchomiony. Zazwyczaj obejmuje to identyfikację procesów gotowych do uruchomienia (na przykład, ponieważ blok, na który czekali, dotarł do pamięci), a także tych, które wyczerpały swój przedział czasu.

Tak więc, kiedy wykonujesz uśpienie wątku, mówisz systemowi operacyjnemu, że (1) rezygnujesz z wycinka czasu i (2) nie powinieneś budzić się ponownie, dopóki nie upłynie określony czas.

Za każdym razem, gdy uruchomi się program planujący, spojrzy na twój wątek i oznaczy go jako „gotowy do uruchomienia”, jeśli ten czas minie. Jest to swego rodzaju odpytywanie, ale nie jest to odpytywanie „zajęte”, ponieważ jest wywoływane przez przerwanie. To również nie jest tak drogie: zwykle na raz działa około tysiąca wątków.

Powinno to również dać ci pojęcie, dlaczego czasy snu nie są dokładne: kiedy wątek jest gotowy do uruchomienia, mogą istnieć inne wątki, które wciąż działają i nie wyczerpały swojego przedziału czasu. Lub mogą istnieć wątki o wyższym priorytecie, które są gotowe do uruchomienia.

kdgregory
źródło
Tak działają „nowoczesne” systemy operacyjne. W starszych systemach operacyjnych, takich jak Windows 3 lub Mac OS wcześniejszy niż OS X, proces musiał podlegać kontroli () systemowi operacyjnemu. Niestety, jeśli program utknie w pętli lub zablokuje się w jakiś sposób, może nigdy nie uzyskać kontroli i cały system się zawiesi.
david25272,
@ david25272 - Myślę, że użyłbym słowa „prostsze” niż „starsze”, ponieważ istniały systemy z lat 60. ubiegłego wieku, które wykonywały zapobiegawczą wielozadaniowość. I chociaż prawdą jest, że wielozadaniowość kooperacyjna wymaga aktywnego wątku, aby zrobić coś, aby zwolnić kontrolę nad procesorem (zwykle poprzez wykonanie blokującego wywołania systemowego, a nie wyraźnej wydajności), nie sądzę, że istnieje wielu programistów ogólnego przeznaczenia dzisiaj, którzy używają systemu operacyjnego ze współpracującym modelem wątków.
kdgregory