2011-01-21 18 views
6

Czytam "sterowniki urządzeń linuksowych 3rd edition", rozdział o współbieżności i warunkach wyścigu. Jest taki przykład, którego nie do końca rozumiem; Mówią o wspólnym schemacie programowania jądra, kiedy trzeba zainicjować działanie (np. rexample, nowy wątek jądra lub proces użytkownika, żądanie dla istniejącego procesu lub działania sprzętowego) poza bieżącym wątkiem, poczekać na działanie kompletny. Przykład nie jest bardzo skuteczne rozwiązanie:jądro Linux mutexes

struct semaphore sem; 
init_MUTEX_LOCKED(&sem); 
start_external_task(&sem); 
down(&sem); 

Potem sugerują zadanie zewnętrznego, aby wywołać (& SEM), gdy jego praca jest wykonywana.

Nie rozumiem, dlaczego nie możemy zrobić to w ten sposób:

struct semaphore sem; 
down(&sem); 
start_external_task(&sem); 

Dlaczego konieczne jest stworzenie mutex w stanie zablokowanym, a następnie nabyć mutex po zadaniu został uruchomiony?

Czekamy na wiadomość od Ciebie! Dzięki.

Odpowiedz

10

Po wywołaniu() wątek będzie blokowany, dopóki inny wątek nie zasygnalizuje semafora. Ponieważ drugi wątek jeszcze się nie rozpoczął, wątek będzie blokował się w nieskończoność. Dlatego najpierw musisz uruchomić wątek, a następnie wywołać funkcję down(), aby zablokować, aż wątek się skończy.

Jeśli wątek zakończy się przed wywołaniem(), to jest w porządku, ponieważ semafor zostanie zasygnalizowany, a naciśnięcie w dół() po prostu usunie sygnał i powróci.

+6

+1, ale myślę, że lepiej byłoby użyć terminu 'semafor' zamiast' mutex'. SEMAPHORE: może być w górę/w dół przez dowolny wątek. MUTEX: ma prawo własności, tylko wątek właściciela blokady może wywołać mutex. W tym przypadku musimy użyć semafora, ponieważ jego celem jest komunikacja między wątkami ... – Vojta

+0

@Vojita: Zgadzam się. Użyłem terminu mutex, ponieważ pytanie odnosi się do semafora jako muteksu. –

3

W pierwszym przykładzie w dół (& sem) będzie czekać na wywołanie metody external_task (& sem) i skutecznie wstrzyma wątek główny do zakończenia zadania. W kodzie w dół() blokuje główny wątek na zawsze, ponieważ nie ma zadanie jeszcze przywołać()

1

Wezwanie:

init_MUTEX_LOCKED(&sem); 

Tworzy nowy semafor w trybie „mutex” zainicjowanego 0. Oznacza to, że połączenie z numerem down() zostanie zablokowane. Odpowiedni wezwanie:

init_MUTEX(&sem); 

stworzyłoby semafora zainicjowany na 1.

W pierwszym przykładzie uruchamiasz semafora 0, stworzyć swój external_task i zadzwonić down() blokowanie dopóki zadanie nazywa up().

W drugim przykładzie nie inicjalizujemy semaforu, nie wywołujemy blokowania down() i nie uruchamiamy zewnętrznego testu zewnętrznego, który może wywołać up(), aby odblokować użytkownika. Wywołanie, aby utworzyć external_task, nigdy nie zostanie osiągnięte.

Nawiasem mówiąc, proces inicjalizacji semafora za pomocą init_MUTEX_LOCKED został usunięty w wersji jądra 2.6.37.

Powiązane problemy