2010-05-05 12 views
8

W Linuksie, kiedy wykonujesz blokujące połączenie typu i-o, takie jak odczyt lub zaakceptuj, co się właściwie dzieje?Jak działa blokowanie wejść/wyjść systemu Linux?

Moje myśli: proces zostanie usunięty z kolejki uruchamiania, wprowadzony do stanu oczekiwania lub zablokowania w niektórych kolejkach oczekiwania. Następnie, gdy zostanie nawiązane połączenie TCP (do akceptacji) lub dysk twardy jest gotowy lub coś do odczytu pliku, powstaje przerwanie sprzętowe, które pozwala tym procesom oczekiwać na przebudzenie i uruchomienie (w przypadku odczytu pliku, w jaki sposób Linux wie, jakie procesy należy przebudzić, ponieważ może być wiele procesów oczekujących na różne pliki?). A może zamiast przerwań sprzętowych, sam proces sam się sprawdza, aby sprawdzić dostępność. Nie wiesz, pomóż?

+0

dość dużo hit gwoździa w głowę (z wyjątkiem ostatniego uwaga, nie ma publicznej, w przeważającej części). Multipleksowanie pomiędzy wielorakimi kelnerami i plikami odbywa się przez jądro, które jest niewidocznym procesem, który koordynuje takie rzeczy w imieniu wszystkich innych procesów. –

Odpowiedz

0

Przeczytaj to: http://www.minix3.org/doc/

To bardzo, jasne, bardzo łatwe do zrozumienia wytłumaczenie. Zasadniczo dotyczy to również systemu Linux.

0

effectivly Ta metoda zwraca tylko wtedy, gdy plik jest gotowy do odczytu, gdy dane jest na gnieździe, gdy połączenie zostanie dostarczona ...

Aby upewnić się, może on powrócić natychmiast prawdopodobnie chcesz użyć Select wywołanie systemowe, aby znaleźć gotowy deskryptor pliku.

11

Każde urządzenie Linux wydaje się być realizowany nieco inaczej, a preferowanym sposobem wydaje się zmieniać co kilka Linux uwalnia jako bezpieczniejsze/szybsze funkcje jądra są dodawane, ale ogólnie:

kierowca
  1. Urządzenie tworzy czytać i Napisz kolejki oczekiwania dla urządzenia.
  2. Każdy wątek procesu, który chce czekać dla operacji we/wy, jest umieszczany w odpowiedniej kolejce oczekiwania . Kiedy przerwanie występuje , budzik budzi jeden lub więcej oczekujących wątków . (Oczywiście wątki nie działają natychmiast, ponieważ jesteśmy w kontekście przerwań , ale są dodawane do kolejki planowania jądra ).
  3. Gdy zaplanowane przez jądro wątek sprawdza, czy warunki są odpowiednie dla kontynuowania - jeśli nie , powraca do kolejki oczekiwania.

Typowym przykładem (nieco uproszczony)

W sterowniku przy inicjalizacji:

init_waitqueue_head(&readers_wait_q); 

w funkcji odczytu kierowcy:

if (filp->f_flags & O_NONBLOCK) 
    { 
     return -EAGAIN; 
    } 
    if (wait_event_interruptible(&readers_wait_q, read_avail != 0)) 
    { 
     /* signal interrupted the wait, return */ 
     return -ERESTARTSYS; 
    } 
    to_copy = min(user_max_read, read_avail); 
    copy_to_user(user_buf, read_ptr, to_copy); 

Następnie przerwanie procedury obsługi tylko wydania:

wake_up_interruptible(&readers_wait_q); 

Należy zauważyć, że wait_event_interruptible() jest makrem, który ukrywa pętlę, która sprawdza warunek - read_avail != 0 w tym przypadku - i wielokrotnie dodaje ponownie do kolejki oczekiwania, jeśli jest ona budzona, gdy warunek nie jest spełniony.

Jak już wspomniano, istnieje wiele odmian - głównym jest to, że jeśli istnieje potencjalnie dużo pracy dla obsługi przerwań, to robi to samo minimum i odrzuca resztę do kolejki pracy lub zadania (ogólnie znana jako "dolna połowa") i to właśnie obudziłoby oczekujące nici.

See Linux Device Driver książka wiecej informacji - pdf dostępny tutaj: http://lwn.net/Kernel/LDD3

Powiązane problemy