2011-12-06 11 views
5

मेरे पास कुछ मल्टीथ्रेड कोड है (प्रश्न Windows API Thread Pool simple example देखें) जिसके लिए मैं एक थ्रेड की पहचान करने के लिए काउंटर का उपयोग कर रहा हूं।InterlockedIncrement vs EnterCriticalSection/काउंटर ++/LeaveCriticalSection

मुझे सलाह दी गई है कि इस काउंटर को थ्रेड के कॉलबैक फ़ंक्शन में बढ़ाने के लिए इंटरलॉक इंस्ट्रूमेंट का उपयोग करें। हालांकि यह वैरिएबल को ठीक तरह से लॉक नहीं लग रहा था, क्योंकि मुझे कुछ समवर्ती मुद्दों का सामना करना पड़ा। मैंने मैन्युअल रूप से महत्वपूर्ण अनुभाग का उपयोग करके इंटरलाक्डइक्रिकमेंट को प्रतिस्थापित किया: EnterCriticalSection/counter ++/LeaveCriticalSection और यह अब पूरी तरह से काम करता है।

ऐसा क्यों है? क्या दो विकल्प सख्ती से समकक्ष नहीं हैं? ध्यान दें कि मैं केवल कुछ जोड़े (लगभग 10) धागे लॉन्च करने के बारे में बात कर रहा हूं।

+0

वैरिएबल को ठीक से लॉक करने के तरीके में ऐसा नहीं लगता था? आपको किस तरह के समेकन के मुद्दों का सामना करना पड़ा? – LukeH

+0

'इंटरलाक्डइनमेंट 'और दोस्तों को लॉक करने की आवश्यकता नहीं है। प्रदर्शन एकल असेंबली निर्देश। क्या आप उन समस्याओं के बारे में अधिक वर्णनात्मक हो सकते हैं जिन्हें आप देख रहे थे? – Nate

+0

ल्यूकएच: काउंटर हमेशा पूर्णांक के लगातार सख्ती से लगातार अनुक्रम नहीं देता था। कभी-कभी 0 से शुरू होने वाला काउंटर कर रहा था: 0 1 2 2 4 5 ... – WhitAngl

उत्तर

26

आपका कोड InterlockedIncrement का उपयोग नहीं कर रहा है।

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

यह thread.threadCount की एक परमाणु वेतन वृद्धि करता है, लेकिन इसके बजाय atomically-वृद्धि मूल्य को बचाने के लिए, आप इसे ध्यान न दें और वापस thread.threadCount चर (जो बीच में एक और धागा द्वारा बढ़ती जा सकता है) के लिए जाना।

आपके मामले में, क्या होता है कि दो धागे एक InterlockedIncrement किया लगभग एक साथ, यह 1 से 2 को बढ़ाने, तो 2 3. करने के लिए दोनों धागे तो thread.threadCount पढ़ सकते हैं और मिल गया 3 वापस (तब 1 घटाया एक अंतिम परिणाम प्राप्त करने के लिए है 2)।

सही कोड

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

अद्वितीय संख्या बढ़ मूल्य InterlockedIncrement द्वारा दिया जाता है। यदि आप अद्वितीय मान देखना चाहते हैं तो आपको अपने गणना में उस मान का उपयोग करने की आवश्यकता है।