W rzeczywistości istnieją trzy gradacje wywołań systemowych.
- Niektóre wywołania systemowe wracają natychmiast. „Natychmiast” oznacza, że jedyne, czego potrzebują, to trochę czasu procesora. Nie ma sztywnego limitu czasu, jaki mogą zająć (z wyjątkiem systemów czasu rzeczywistego ), ale połączenia te wracają, gdy tylko zostaną zaplanowane wystarczająco długo.
Te połączenia są zwykle nazywane nieblokującymi . Przykłady połączeń bez blokowania połączeń, które są po prostu przeczytać kawałek stanu systemu, lub dokonać prostej zmiany stanu systemu, takie jak getpid
, gettimeofday
, getuid
lub setuid
. Niektóre wywołania systemowe mogą blokować lub nie blokować w zależności od okoliczności; na przykład read
nigdy nie blokuje, jeśli plik jest potokiem lub innym typem, który obsługuje nieblokujące odczyty i ustawiona jest O_NONBLOCK
flaga .
- Wykonanie kilku wywołań systemowych może trochę potrwać, ale nie na zawsze. Typowym przykładem jest
sleep
.
- Niektóre wywołania systemowe nie powrócą, dopóki nie nastąpi jakieś zdarzenie zewnętrzne. Mówi się, że te połączenia są blokowane . Na przykład
read
wywołany blokujący deskryptor pliku blokuje, podobnie jak wait
.
Rozróżnienie między „szybkimi” i „powolnymi” wywołaniami systemowymi jest bliskie nieblokowaniu vs. blokowaniu, ale tym razem z punktu widzenia implementatora jądra. Szybki syscall to taki, który jest w stanie wykonać bez blokowania lub oczekiwania. Kiedy jądro napotyka szybkie wywołanie systemowe, wie, że może natychmiast wykonać wywołanie systemowe i zaplanować ten sam proces. (W niektórych systemach operacyjnych z nieprzezwyciężającą wielozadaniowością szybkie wywołania systemowe mogą nie działać zapobiegawczo; nie dzieje się tak w normalnych systemach unixowych). Z drugiej strony powolne wywołanie systemowe potencjalnie wymaga oczekiwania na zakończenie innego zadania, więc jądro należy przygotować się do wstrzymania procesu wywoływania i uruchomienia innego zadania.
Niektóre przypadki są trochę szare. Na przykład odczyt dysku ( read
ze zwykłego pliku) jest zwykle uważany za nieblokujący, ponieważ nie czeka na inny proces; czeka tylko na dysk, który zwykle zajmuje tylko trochę czasu, ale nie potrwa wiecznie (tak jest w przypadku 2 powyżej). Ale z punktu widzenia jądra proces musi czekać na zakończenie pracy sterownika dysku, więc jest to zdecydowanie powolne wywołanie systemowe.
Gilles „SO- przestań być zły”
źródło
O_NONBLOCK
flagi. Jeśli flaga jest ustawiona, syscall może zakończyć się bez czekania na cokolwiek innego, więc nie jest blokujący, a jądro może potraktować to jako szybkie syscall.Wolne wywołanie systemowe przypomina coś w rodzaju gniazda TCP read () - jeśli nie masz ustawionego O_ASYNC (lub cokolwiek innego), może czekać na zawsze.
Szybkie wywołanie systemowe przypomina gettimeofday () lub getpid (), które zwracają informacje do procesu, który jądro ma natychmiast dostępne.
Odczyty dysków należą do kategorii powolnych wywołań systemowych. Jeśli proces wykonuje odczyt () na prawdziwym pliku dyskowym, deskryptorze pliku, jądro może potrzebować odczytu w jednym lub większej liczbie bloków dysku, aby spełnić wymagania odczytu. W zależności od struktury systemu plików na dysku systemu plików, może to oznaczać odczytanie i-węzła na dysku w celu uzyskania numeru bloku dysku „bloku pośredniego”, odczytanie bloku pośredniego w celu uzyskania bloku danych, a następnie odczytanie samego bloku danych . Dość czasochłonne, przynajmniej pod względem liczby cykli procesora na dostęp do dysku, prawdopodobnie dziś gorzej niż w czasach dobrych, dobrych czasów.
Nie widziałem tego od wieków, ale „dolna połowa” starego sterownika uniksowego urządzenia dyskowego blokowałaby sygnały / przerwania, aby łatwiej było zachować integralność systemu plików na dysku. Czasami wadliwy sterownik lub uszkodzony dysk nigdy nie dostarczałby bloku dysku, o który prosił proces, a proces spał na zawsze. Nawet zabójstwo -9 nic nie zrobiło.
źródło