İki (veya daha fazla) ipliğin aynı anda kilitlenmesi mümkün değildir. Örneğin, birkaç tür senkronizasyon yöntemi vardır:
Aktif bekleme - sıkma kilidi
pseudocode:
1. while ( xchg(lock, 1) == 1); - entry protocole
XCHG, önce bir "kilit" değişkeni için yeni bir değer ayarlayan ve daha sonra eski değeri döndüren bir atomik işlem örneğidir (x86 mimarisinde var). Atomik, kesilemeyeceği anlamına gelir - yukarıdaki örnekte yeni değer ayarlama ve eskiye dönüş arasında. Atomik - deterministik sonuç ne olursa olsun.
2. Your code
3. lock = 0; - exit protocol
Kilit 0'a eşit olduğunda, kritik bölüme başka bir diş girebilir - döngü biter.
İplik askıya alma - örneğin semafor sayımı
İki atomik işlem var .Wait()
ve .Signal()
tamsayı değişkenimiz onu çağırmamıza izin veriyor 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;
Şimdi kritik bölüm problemini çözmek gerçekten kolay:
pseudocode:
mySemaphore.Wait();
do some operations - critical section
mySemaphore.Signal();
Genellikle programlama iş parçacığı API'niz semafor kritik bölümünde en fazla eşzamanlı iş parçacığı belirtebilmenizi sağlar. Açıkçası, çok iş parçacıklı sistemlerde (mutex, monitörler, ikili semafor vb.) Daha fazla senkronizasyon türü var, ancak yukarıdaki fikirlere dayanıyorlar. İplik askıya alma yöntemlerinin aktif beklemede tercih edilmesi gerektiği söylenebilir (böylece cpu israf edilmez) - bu her zaman gerçek değildir. İplik askıya alındığında - bağlam anahtarı adı verilen pahalı işlem gerçekleşir. Ancak, bekleme süresi kısa olduğunda (diş sayısı ~ çekirdek sayısı) makul olur.