Od czytania stron podręcznika man po wywołaniach 'read ()' i 'write ()' wydaje się, że wywołania te są przerywane przez sygnały niezależnie od tego, czy muszą one zostać zablokowane, czy nie.
W szczególności załóżmy
- proces ustanawia procedurę obsługi pewnego sygnału.
- urządzenie jest otwierane (powiedzmy terminal ...) przy braku ustawienia „O_NONBLOCK” (tzn. działającego w trybie blokowania)
- proces wykonuje wywołanie systemowe read () do odczytu z urządzenia iw rezultacie wykonuje ścieżkę kontroli jądra w przestrzeni jądra.
- podczas gdy proces wykonuje swoje 'read ()' w przestrzeni jądra, sygnał, dla którego program obsługi został wcześniej zainstalowany, jest dostarczany do tego procesu i wywoływany jest jego program obsługi sygnału.
Czytanie stron podręcznika systemowego i odpowiednich sekcji w SUSv3 'System Interfaces volume (XSH)' stwierdza, że:
ja. Jeśli odczyt () zostanie przerwany przez sygnał przed odczytaniem jakichkolwiek danych (tj. Musiał on zostać zablokowany, ponieważ żadne dane nie były dostępne), zwraca -1 z „errno” ustawionym na [EINTR].
ii. Jeśli odczyt () zostanie przerwany przez sygnał po pomyślnym odczytaniu niektórych danych (tj. Można było natychmiast rozpocząć obsługę żądania), zwraca liczbę odczytanych bajtów
Pytanie A:
Czy mam rację zakładając, że w obu przypadkach (blok / brak bloku) dostarczanie i obsługa sygnału nie jest całkowicie przezroczysta dla „read ()”?
Sprawa i. wydaje się zrozumiałe, ponieważ blokowanie „read ()” normalnie umieszcza proces w stanie „TASK_INTERRUPTIBLE”, tak że gdy sygnał jest dostarczany, jądro umieszcza proces w stanie „TASK_RUNNING”.
Jednak gdy 'read ()' nie musi blokować (przypadek ii.) I przetwarza żądanie w przestrzeni jądra, pomyślałbym, że pojawienie się sygnału i jego obsługa byłyby przejrzyste, podobnie jak nadejście i właściwe byłoby przerwanie HW. W szczególności założyłbym, że po dostarczeniu sygnału proces zostanie tymczasowo umieszczony w USER-MODE, aby wykonać jego program obsługi sygnału, z którego w końcu powróci, aby zakończyć przetwarzanie przerwanego „read ()” (w przestrzeni jądra ) tak, że 'read ()' biegnie do końca, po czym proces powraca do punktu zaraz po wywołaniu 'read ()' (w przestrzeni użytkownika), z wszystkimi dostępnymi bajtami odczytanymi jako wynik .
Ale ii. wydaje się sugerować, że „read ()” jest przerwane, ponieważ dane są dostępne natychmiast, ALE zwraca dane „niektóre” danych (zamiast wszystkich).
To prowadzi mnie do drugiego (i ostatniego) pytania
Pytanie B):
Jeśli moje założenie w punkcie A) jest poprawne, to dlaczego „read ()” zostaje przerwane, nawet jeśli nie musi się blokować, ponieważ dostępne są dane, aby natychmiast spełnić żądanie? Innymi słowy, dlaczego „read ()” nie jest wznawiane po wykonaniu procedury obsługi sygnału, co ostatecznie skutkuje zwróceniem wszystkich dostępnych danych (które w końcu były dostępne)?