Nie jest możliwe, aby dwa (lub więcej) wątków uzyskało blokadę w tym samym czasie. Istnieje kilka rodzajów metod synchronizacji, na przykład:
Aktywne oczekiwanie - spin lock
Pseudo kod:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG jest przykładem operacji atomowej (istniejącej w architekturze x86), która najpierw ustawia nową wartość dla zmiennej „lock”, a następnie zwraca starą wartość. Atom oznacza, że nie można go przerwać - w powyższym przykładzie między ustawieniem nowej wartości a zwróceniem starej. Atomowy - deterministyczny wynik bez względu na wszystko.
2. Your code
3. lock = 0; - exit protocol
Gdy blokada jest równa 0, inny wątek może wejść do sekcji krytycznej - podczas gdy pętla się kończy.
Zawieszenie wątku - na przykład liczenie semafora
Istnieje dwa operację atomową .Wait()
a .Signal()
i mamy całkowitą zmienna pozwala wywołać int currentValue
.
Wait():
if (currentValue > 0) currentValue -= 1;
else suspend current thread;
Signal():
If there exists thread suspended by semaphore wake up one of them
Else currentValue += 1;
Teraz rozwiązanie problemu sekcji krytycznej jest naprawdę łatwe:
Pseudo kod:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
Zwykle interfejs API wątku programistycznego powinien umożliwiać określenie maksymalnych współbieżnych wątków w sekcji krytycznej dla semaforów. Oczywiście istnieje więcej rodzajów synchronizacji w systemach wielowątkowych (mutex, monitory, binarny semafor itp.), Ale opierają się one na powyższych pomysłach. Można argumentować, że metody wykorzystujące zawieszanie wątków powinny być preferowane zamiast aktywnego oczekiwania (więc procesor nie jest marnowany) - nie zawsze jest to prawda. Gdy wątek jest zawieszany - ma miejsce kosztowna operacja zwana przełączaniem kontekstu. Jest to jednak rozsądne, gdy czas oczekiwania jest krótki (liczba wątków ~ liczba rdzeni).