2008-09-16 13 views
41

pthread_cond_wait या सेमफोर का उपयोग करने के पेशेवर/विपक्ष क्या हैं? मैं इस तरह के एक राज्य में परिवर्तन के लिए इंतज़ार कर रहा हूँ:pthread_cond_wait बनाम सेमफोर

pthread_mutex_lock(&cam->video_lock); 
while(cam->status == WAIT_DISPLAY) { 
    pthread_cond_wait(&cam->video_cond, &cam->video_lock); 
} 
pthread_mutex_unlock(&cam->video_lock); 

एक ठीक से initialised सेमाफोर का उपयोग करना, मुझे लगता है कि मैं इसे इस तरह कर सकता है:

while(cam->status == WAIT_DISPLAY) { 
    sem_wait(&some_semaphore); 
} 

पेशेवरों और प्रत्येक विधि के विपक्ष क्या हैं?

+0

मैं सिर्फ महसूस किया कि "ठीक से प्रारंभ सेमाफोर" ख़राब ढंग से परिभाषित किया गया है। क्या सैमफोर 1 या 0 तक सेट है? मैं कहूंगा कि इसे 0 पर सेट किया जाना चाहिए। फिर, क्या सैमफोर कैम-> स्थिति की रक्षा करता है या नहीं? – Blaisorblade

+0

दूसरे स्निपेट में, जैसा कि अन्य उत्तरों में उल्लिखित है, म्यूटेक्स जारी नहीं होने पर आपका धागा अवरुद्ध हो जाएगा। तो आपकी 'sem_wait' विधि कभी वापस नहीं आएगी क्योंकि कोई अन्य थ्रेड म्यूटेक्स प्राप्त नहीं कर सकता है और' sem_signal 'को कॉल कर सकता है। हालांकि, अगर मैं 'sem_wait' से पहले mutex जारी करता हूं और प्रतीक्षा के बाद इसे फिर से आवश्यकता होती है तो मैं नहीं करूँगा। मुझे पता है कि ये कदम परमाणु नहीं हैं, तो क्या होगा? – sevenkplus

उत्तर

58

एक सेमफोर निर्माता-उपभोक्ता मॉडल के लिए स्पष्ट रूप से उपयुक्त है, हालांकि इसमें अन्य उपयोग हैं। आपका प्रोग्राम तर्क यह सुनिश्चित करने के लिए ज़िम्मेदार है कि प्रतीक्षा की संख्या के लिए पदों की सही संख्या बनाई गई है। यदि आप एक सेमफोर पोस्ट करते हैं और कोई भी इस पर इंतजार नहीं कर रहा है, तो जब वे प्रतीक्षा करते हैं तो वे तुरंत जारी रहते हैं। यदि आपकी समस्या ऐसी है कि इसे सेमफोर के गिनती मूल्य के संदर्भ में समझाया जा सकता है, तो इसे सेफफोर के साथ हल करना आसान होना चाहिए।

एक शर्त चर कुछ मामलों में थोड़ा और क्षमा कर रहा है। उदाहरण के लिए आप सभी वेटर्स को जागृत करने के लिए cond_broadcast का उपयोग कर सकते हैं, निर्माता के बिना यह जानने के लिए कि कितने हैं। और यदि आप किसी कन्वेयर को cond_signal करते हैं तो इसके साथ कोई भी इंतजार नहीं करता है तो कुछ भी नहीं होता है। यह अच्छा है अगर आपको पता नहीं है कि कोई श्रोता रुचि रखने वाला है या नहीं। यही कारण है कि श्रोता को हमेशा इंतजार करने से पहले म्यूटेक्स के साथ राज्य की जांच करनी चाहिए - अगर वे नहीं करते हैं तो वे एक सिग्नल याद कर सकते हैं और अगले तक जाग नहीं सकते (जो कभी नहीं हो सकता है)।

तो एक शर्त चर रुचि रखने वाले पक्षों को सूचित करने के लिए उपयुक्त है कि राज्य बदल गया है: आप म्यूटेक्स प्राप्त करते हैं, राज्य को बदलते हैं, सिग्वर (या प्रसारण) कंडवार को बदलते हैं और म्यूटेक्स को छोड़ देते हैं। यदि यह आपकी समस्या का वर्णन करता है तो आप कन्वेयर क्षेत्र में हैं। यदि विभिन्न श्रोताओं को अलग-अलग राज्यों में दिलचस्पी है तो आप बस प्रसारण कर सकते हैं और वे प्रत्येक बदले में जागृत हो जाएंगे, यह पता लगाएंगे कि उन्हें वह राज्य मिला है जो वे चाहते हैं, और यदि फिर से इंतजार नहीं किया जाता है।

यह वास्तव में एक म्यूटेक्स और सेमफोर के साथ इस तरह की चीज का प्रयास करने के लिए बहुत गहराई से है। समस्या तब आती है जब आप म्यूटेक्स लेना चाहते हैं, कुछ राज्य जांचें, फिर परिवर्तनों के लिए सेमफोर पर प्रतीक्षा करें। जब तक आप परमाणु रूप से म्यूटेक्स को छोड़ नहीं सकते और सेमफोर (जो कि आप जो नहीं कर सकते हैं) में प्रतीक्षा करते हैं, तो आप म्यूटेक्स धारण करते समय सेमफोर पर प्रतीक्षा कर सकते हैं। यह म्यूटेक्स को अवरुद्ध करता है, जिसका अर्थ यह है कि अन्य लोग उस बदलाव को बदलने के लिए नहीं ले सकते हैं जिसकी आप परवाह करते हैं। तो आप एक और म्यूटेक्स को इस तरह से जोड़ने का लुत्फ उठाएंगे जो आपकी विशिष्ट आवश्यकताओं पर निर्भर करता है। और शायद एक और सेमफोर। नतीजा आम तौर पर हानिकारक दौड़ की स्थिति के साथ गलत कोड है।

कंडीशन चर इस समस्या से बचते हैं, क्योंकि cond_wait को कॉल करना स्वचालित रूप से म्यूटेक्स को रिलीज़ करता है, इसे दूसरों द्वारा उपयोग के लिए मुक्त करता है। Mutex cond_wait रिटर्न से पहले वापस प्राप्त किया जाता है।

आईआईआरसी केवल सेफफोर्स का उपयोग करके एक प्रकार का कन्वेयर लागू करना संभव है, लेकिन अगर आप जिस म्यूटेक्स को कन्वेयर के साथ जाने के लिए कार्यान्वित कर रहे हैं, उसे ट्रायलॉक करना आवश्यक है, तो यह एक गंभीर सिर-स्क्रैचर है, और समय की प्रतीक्षा । सिफारिश नहीं की गई। इसलिए यह न मानें कि कंडवर के साथ आप जो कुछ भी कर सकते हैं वह सेफफोर्स के साथ किया जा सकता है। इसके अलावा म्यूटेक्स के अच्छे व्यवहार हो सकते हैं कि सेमेफोर की कमी, मुख्य रूप से प्राथमिकता-उलटा बचाव।

0

अपने दूसरे स्निपेट में, आपको कई बार लॉक मिल रहा है, इसे कभी जारी नहीं किया जा रहा है।

आम तौर पर, जिस राज्य में आप वाइनिन हैं, उसे सैमफोर द्वारा पूरी तरह व्यक्त किया जा सकता है, तो आप इसका उपयोग कर सकते हैं। एक ताला संरचना आकार में छोटा है, और इसे जांच/सेट/रिलीज़ करने के लिए कम परमाणु संचालन की आवश्यकता होती है।

अन्यथा, यदि राज्य जटिल है, और कोड के विभिन्न हिस्सों एक ही चर की विभिन्न स्थितियों पर प्रतीक्षा करते हैं (उदाहरण के लिए, यहां आप x < 10 चाहते हैं; वहां आप y> x चाहते हैं), cond_wait का उपयोग करें।

+0

दूसरा स्निपेट सही है - एक जागरूकता हमेशा सेमफोर को सिग्नल करने वाले किसी के कारण होती है। – Blaisorblade

+0

@ ब्लाइसोरब्लैड, जागने सही है, स्थिति जांच नहीं है क्योंकि इसकी सुरक्षा नहीं है। –

+0

यह उत्तर क्या है इसका वर्णन करने की तुलना में यह एक अलग समस्या है - "आपके दूसरे स्निपेट में, आपको कई बार लॉक मिल रहा है, इसे कभी जारी नहीं किया जा रहा है"। मैं उपरोक्त मेरे उत्तर में इस समस्या का उल्लेख करता हूं (हालांकि बहुत विशेष रूप से नहीं)। लेकिन कोड पर फिर से देखकर, मुझे एहसास हुआ कि कोई वास्तव में यह नहीं बता सकता कि दूसरा स्निपेट सही है या नहीं, क्योंकि बहुत सारे विवरण गुम हैं (प्रश्न पर मेरी टिप्पणी देखें)। लेकिन मैंने अपनी टिप्पणी गलत तरीके से phrased - मुझे यह कहना चाहिए था कि "आप जिस समस्या का उल्लेख करते हैं वह वहां नहीं है, क्योंकि ..."। – Blaisorblade

19

कंडीशनल आपको कुछ चीजें करने देते हैं जो सेमफोर नहीं करेंगे।

उदाहरण के लिए, मान लें कि आपके पास कुछ कोड है जिसके लिए एक म्यूटेक्स की आवश्यकता है, जिसे m कहा जाता है। हालांकि इसे तब तक इंतजार करने की ज़रूरत है जब तक कि कुछ अन्य धागे ने अपना काम पूरा नहीं किया हो, इसलिए यह s नामक एक सेमफोर पर इंतजार कर रहा है। अब m की आवश्यकता वाले किसी भी थ्रेड को चलने से अवरुद्ध किया गया है, भले ही m पर थ्रेड s पर प्रतीक्षा कर रहा है। इस तरह की स्थितियों को सशर्तों का उपयोग करके हल किया जा सकता है। जब आप एक सशर्त पर प्रतीक्षा करते हैं, तो वर्तमान में आयोजित म्यूटेक्स जारी किया जाता है, इसलिए अन्य धागे म्यूटेक्स प्राप्त कर सकते हैं। तो हमारे उदाहरण पर वापस जाएं, और मान लें कि सशर्त c का उपयोग s के बजाय किया गया था। हमारा धागा अब m प्राप्त करता है, और फिर सशर्त c पर प्रतीक्षा करता है। यह m जारी करता है ताकि अन्य धागे आगे बढ़ सकें। जब c उपलब्ध हो जाता है, m पुनः प्राप्त किया जाता है, और हमारा मूल धागा इसके रास्ते में आसानी से जारी रख सकता है।

सशर्त चर आपको सभी थ्रेड को सशर्त चर पर प्रतीक्षा करने के लिए pthread_cond_broadcast के माध्यम से आगे बढ़ने की अनुमति देता है। इसके अतिरिक्त यह आपको समयबद्ध प्रतीक्षा करने की अनुमति देता है ताकि आप हमेशा के लिए प्रतीक्षा न करें।

बेशक, कभी-कभी आपको सशर्त चर की आवश्यकता नहीं होती है, इसलिए आपकी आवश्यकताओं के आधार पर, एक या दूसरा बेहतर हो सकता है।

+3

यह एक अच्छा जवाब है। विवरण में जोड़ने के लिए, म्यूटेक्स और सेमफोर के वर्णित संयोजन से संबंधित सशर्त अद्वितीय क्या बनाता है कि सशर्त म्यूटेक्स/सेमफोर जोड़ी परमाणु रूप से कुशलतापूर्वक उपयोग करता है !! –

4

दूसरा स्निपेट दुर्लभ है, ऐसा मत करो।

अन्य उत्तरों के सापेक्ष गुणों की अच्छी चर्चा है; मैं बस जोड़ दूंगा कि pthread_cond_broadcast हालत चर के स्पष्ट लाभ है।

इसके अलावा, मैं इसके लिए कंडीशन चर के लिए और अधिक उपयोग कर रहा हूं, क्योंकि वे जावा में आप जो भी उपयोग करते हैं, भले ही वे साझा झंडे की जांच करते समय दौड़ से बचने में आपकी सहायता करते हैं।

दरअसल, दूसरे स्निपेट में आपके पास कैमरे>> स्थिति के पढ़ने की कोई तालाब नहीं है, इसलिए इसे डेटा रेस के माध्यम से एक्सेस किया जाता है। अधिकांश प्लेटफार्म आपको इस विशेष उदाहरण में इससे दूर जाने देंगे, लेकिन इसने पीओएसआईक्स द्वारा और अगले सी/सी ++ मानकों के मेमोरी मॉडल द्वारा अर्थशास्त्र को अपरिभाषित किया है।

वास्तव में, एक वास्तविक थ्रेड स्थिति संभव है यदि कोई अन्य धागा एक नई कैम संरचना आवंटित करता है और कैमरे को ओवरराइट करता है; प्रतीक्षा थ्रेड कैमरे की स्थिति को शुरू किए बिना 'कैम' पॉइंटर को अपडेट देख सकता है। वास्तव में, दूसरा स्निपेट इस मामले में और सामान्य रूप से परेशानी के लिए पूछ रहा है।

http://www.hpl.hp.com/personal/Hans_Boehm/c++mm/

+0

वास्तव में, दूसरे स्निपेट में सेमफोर स्वयं स्थिति ध्वज (या नहीं) की रक्षा कर सकता है (हालांकि मैं इसके लिए एक अच्छा लॉकिंग प्रोटोकॉल कल्पना नहीं कर सकता)। – Blaisorblade

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