2013-06-03 10 views
11

मैंने निर्माता-उपभोक्ता मॉडल का उपयोग करके पर्थ्रेड के साथ एक बहु-थ्रेड प्रोग्राम लिखा था।पर्थ्रेड म्यूटेक्स: pthread_mutex_unlock() बहुत समय का उपभोग करता है

जब मैं अपने प्रोग्राम को प्रोफाइल करने के लिए इंटेल वीट्यून प्रोफाइलर का उपयोग करता हूं, तो मुझे लगता है कि निर्माता और उपभोक्ता pthread_mutex_unlock पर बहुत समय बिताते हैं। मुझे समझ में नहीं आया कि ऐसा क्यों हुआ। मुझे लगता है कि धागे एक म्यूटेक्स प्राप्त करने से पहले लंबे समय तक इंतजार कर सकते हैं, लेकिन एक म्यूटेक्स जारी करना तेज होना चाहिए, है ना?

नीचे स्नैपशॉट इंटेल VTune से है। यह उन कोडों को दिखाता है जहां उपभोक्ता बफर से किसी आइटम को लाने की कोशिश करता है, और प्रत्येक कोड लाइन द्वारा खपत समय।

मेरा सवाल यह है कि क्यों pthread_mutex_unlock का उपर है? क्या pthread mutex के साथ समस्या या जिस तरह से मैं इसका उपयोग करता हूं? enter image description here

+0

उस म्यूटेक्स पर बहुत अधिक विवाद होने पर एक म्यूटेक्स को अनलॉक करना धीमा हो सकता है, क्योंकि अनलॉकिंग के काम का हिस्सा म्यूटेक्स पर इंतजार कर रहे किसी भी थ्रेड को जागृत कर रहा है। – caf

+6

मुझे लगता है कि अगर आप 'pthread_mutex_unlock()' कॉल को कॉल के ऊपर 'pthread_cond_signal()' पर ले जाते हैं तो परिणाम देखना दिलचस्प होगा। कंडीशन वैरिएबल को सिग्नल करते समय म्यूटक्स को पकड़ने की कोई आवश्यकता नहीं है (केवल उस पर प्रतीक्षा करते समय), और मुझे संदेह है कि सिग्नल म्यूटेक्स पर विवाद का कारण बनता है क्योंकि थ्रेड जो तुरंत रिलीज हो जाता है वह म्यूटेक्स हासिल करने का प्रयास करता है, जो कि सिग्नलिंग थ्रेड अभी भी रखता है। –

+2

@MichaelBurr अच्छा बिंदु! मैं आपके सुझाव के साथ परीक्षण करता हूं और कार्यक्रम अब लगभग 40% तेज है। –

उत्तर

2

pthread_mutex_unlock() फ़ंक्शन mutex द्वारा संदर्भित म्यूटेक्स ऑब्जेक्ट को रिलीज़ करेगा। लेकिन, जिस तरीके से एक म्यूटेक्स जारी किया जाता है वह म्यूटेक्स के प्रकार की विशेषता पर निर्भर होता है। यदि mthx द्वारा संदर्भित mutex ऑब्जेक्ट पर थ्रेड्स अवरुद्ध होते हैं, जब pthread_mutex_unlock() को कॉल किया जाता है, जिसके परिणामस्वरूप म्यूटक्स उपलब्ध हो जाता है, तो शेड्यूलिंग नीति निर्धारित करेगी कि कौन सा थ्रेड म्यूटेक्स प्राप्त करेगा।

यदि म्यूटेक्स प्रकार PTHREAD_MUTEX_NORMAL है, तो डेडलॉक पहचान प्रदान नहीं की जाएगी। म्यूटक्स को रिलाक करने का प्रयास डेडलॉक का कारण बनता है। यदि कोई थ्रेड एक म्यूटेक्स को अनलॉक करने का प्रयास करता है जिसे उसने लॉक नहीं किया है या एक म्यूटेक्स जो अनलॉक किया गया है, अपरिभाषित व्यवहार परिणाम।

यदि म्यूटेक्स प्रकार PTHREAD_MUTEX_ERRORCHECK है, तो त्रुटि जांच प्रदान की जाएगी। यदि कोई थ्रेड एक म्यूटेक्स को फिर से लॉक करने का प्रयास करता है जिसे वह पहले ही लॉक कर चुका है, तो एक त्रुटि वापस कर दी जाएगी। यदि कोई थ्रेड किसी म्यूटेक्स को अनलॉक करने का प्रयास करता है जिसे उसने लॉक नहीं किया है या एक म्यूटेक्स जो अनलॉक है, तो एक त्रुटि लौटा दी जाएगी।

यदि म्यूटेक्स प्रकार PTHREAD_MUTEX_RECURSIVE है, तो म्यूटेक्स लॉक गिनती की अवधारणा को बनाए रखेगा। जब एक धागा पहली बार म्यूटेक्स को सफलतापूर्वक प्राप्त करता है, तो लॉक गिनती एक पर सेट की जाएगी। हर बार जब एक थ्रेड इस म्यूटेक्स को बंद कर देता है, तो लॉक गिनती एक से बढ़ी जाएगी। प्रत्येक बार जब थ्रेड म्यूटेक्स को अनलॉक करता है, तो लॉक गिनती एक से कम हो जाएगी। जब लॉक गिनती शून्य तक पहुंच जाती है, तो म्यूटेक्स अन्य धागे के अधिग्रहण के लिए उपलब्ध हो जाएगा। यदि कोई थ्रेड किसी म्यूटेक्स को अनलॉक करने का प्रयास करता है जिसे उसने लॉक नहीं किया है या एक म्यूटेक्स जो अनलॉक है, तो एक त्रुटि लौटा दी जाएगी।

यदि म्यूटेक्स प्रकार PTHREAD_MUTEX_DEFAULT है, तो mutex परिणामों को निरंतर व्यवहार में लॉक करने का प्रयास कर रहा है। म्यूटेक्स को अनलॉक करने का प्रयास अगर इसे कॉलिंग थ्रेड द्वारा लॉक नहीं किया गया है तो अपरिभाषित व्यवहार में परिणाम। म्यूटक्स को अनलॉक करने का प्रयास अगर यह लॉक नहीं किया गया है तो अपरिभाषित व्यवहार में परिणाम।

मैं आम तौर पर PTHREAD_MUTEX_RECURSIVE म्यूटेक्स का उपयोग करना पसंद करता हूं, क्योंकि इस मामले में जब mउंटx शून्य तक पहुंच जाता है और कॉलिंग थ्रेड के पास इस म्यूटेक्स पर कोई ताला नहीं होता है तो म्यूटेक्स उपलब्ध हो जाएगा।

संबंधित मुद्दे