2011-12-06 8 views
5

Bir iş parçacığı tanımlamak için bir sayaç kullanıyorum bazı çok iş parçacıklı kodum var (Soru Windows API Thread Pool simple example soru).InterlockedIncrement vs EnterCriticalSection/counter ++/LeaveCriticalSection

Bu sayacı iş parçacığının geri çağırma işlevinde artırmak için bir InterlockedIncrement kullanmanız önerildi. Ancak bu, bazı eşzamanlılık sorunları ile karşılaştığımda, değişkeni düzgün bir şekilde kilitlemiyor gibi görünüyordu. InterlockedIncrement'ı el ile kritik bir bölüm kullanarak değiştirdim: EnterCriticalSection/counter ++/LeaveCriticalSection ve bu şimdi mükemmel çalışıyor.

Neden böyle? İki seçeneğin kesinlikle eşdeğer olması gerekmiyor mu? Not: Ben sadece bir çift (yaklaşık 10) iş parçacığı başlatılması hakkında konuşuyorum.

+0

Bu şekilde, değişkeni düzgün bir şekilde kilitlemediniz mi? Hangi eşzamanlılık sorunları ile karşılaştınız? – LukeH

+0

'InterlockedIncrement' ve arkadaşların kilitlenmesine gerek yoktur. Tek montaj talimatları gerçekleştirin. Gördüğünüz sorunlar hakkında daha açıklayıcı olabilir misiniz? – Nate

+0

LukeH: sayaç her zaman tam olarak art arda ardışık bir tamsayı dizisi vermedi. Bazen, 0'dan başlayarak, sayaç yapıyordu: 0 1 2 2 4 5 ... – WhitAngl

cevap

26

Kodunuz InterlockedIncrement numaralı telefonu doğru bir şekilde kullanmıyor.

InterlockedIncrement(&(thread.threadCount)); 
DWORD tid = (thread.threadCount-1)%thread.size(); 

Bu thread.threadCount bir atom artış gerçekleştiren, ancak bunun yerine atomik-arttırılmış değerini kaydederek, bunu göz ardı edip geri (aynı anda başka bir iş parçacığı tarafından artırılır olabilir) thread.threadCount değişkene gidin. Senin durumunda

ne olur iki konu her iki diş sonra thread.threadCount okumak ve 3 sırt (daha sonra nihai sonuç almak için 1 çıkarılır var 2 3., sonra 1'den 2'ye bunu bir arttırılarak neredeyse eşzamanlı bir InterlockedIncrement yaptığıdır 2).

doğru kod benzersiz arttırılmış değer InterlockedIncrement tarafından döndürülen

LONG tidUnique = InterlockedIncrement(&(thread.threadCount)); 
DWORD tid = (tidUnique-1)%thread.size(); 

olup. Eşsiz değeri görmek istiyorsanız, bu değeri hesaplamalarınızda kullanmanız gerekir.

İlgili konular