हमें म्यूटेक्स का उपयोग कब करना चाहिए और हमें सेमाफोर का उपयोग कब करना चाहिए?
हमें म्यूटेक्स का उपयोग कब करना चाहिए और हमें सेमाफोर का उपयोग कब करना चाहिए?
जवाबों:
यहाँ है कि मुझे याद है कि कब क्या उपयोग करना है -
सेमाफोर: जब आप (थ्रेड) सोना चाहते हैं तब तक एक सेमाफोर का उपयोग करें जब तक कि कोई अन्य धागा आपको जागने के लिए नहीं कहता। सेमाफोर 'डाउन' एक थ्रेड (निर्माता) में होता है और सेमाफोर 'अप' (एक ही सेमाफोर के लिए) दूसरे थ्रेड (उपभोक्ता) में होता है जैसे: निर्माता-उपभोक्ता समस्या में, निर्माता कम से कम एक बफर स्लॉट खाली होने तक सोना चाहता है - केवल उपभोक्ता थ्रेड बता सकता है कि बफर स्लॉट कब खाली है।
म्युटेक्स: एक म्युटेक्स उपयोग जब आप (धागा) कोड है कि किसी भी अन्य धागे से एक ही समय में नहीं निष्पादित किया जाना चाहिए पर अमल करना चाहते हैं। म्युटेक्स 'नीचे' एक धागा और म्युटेक्स 'ऊपर' में होता है चाहिए पर बाद में एक ही धागे में होती हैं। उदाहरण: यदि आप किसी वैश्विक लिंक्ड सूची से नोड को हटा रहे हैं, तो आप नोड को हटाते समय पॉइंटर्स के साथ एक और थ्रेड नहीं डालना चाहते। जब आप म्यूटेक्स प्राप्त करते हैं और एक नोड को हटाने में व्यस्त होते हैं, यदि कोई अन्य थ्रेड एक ही म्यूटेक्स को प्राप्त करने की कोशिश करता है, तो इसे म्यूटेक्स जारी करने तक सोने के लिए रखा जाएगा।
स्पिनलॉक: जब आप वास्तव में म्यूटेक्स का उपयोग करना चाहते हैं तो एक स्पिनलॉक का उपयोग करें लेकिन आपके धागे को सोने की अनुमति नहीं है। उदाहरण: ओएस कर्नेल के भीतर एक बाधा हैंडलर कभी नहीं सोना चाहिए। यदि ऐसा होता है तो सिस्टम फ्रीज / क्रैश हो जाएगा। यदि आपको बाधा हैंडलर से वैश्विक रूप से साझा की गई सूची में नोड सम्मिलित करने की आवश्यकता है, तो एक स्पिनलॉक - नोड डालें - रिलीज़ स्पिनलॉक प्राप्त करें।
एक म्यूटेक्स एक पारस्परिक बहिष्करण वस्तु है, जो एक सेमाफोर के समान है लेकिन यह केवल एक समय में एक लॉकर की अनुमति देता है और जिसका स्वामित्व प्रतिबंध सेमीफोर से अधिक कठोर हो सकता है।
इसे एक सामान्य गिनती के सेमाफोर के बराबर माना जा सकता है (एक की गिनती के साथ) और आवश्यकता है कि इसे केवल उसी धागे से जारी किया जा सकता है जिसने इसे (ए) लॉक किया था ।
दूसरी ओर, एक सेमीफोर में एक मनमाना गिनती होती है और इसे कई लॉकर समवर्ती रूप से लॉक कर सकते हैं। और इसकी आवश्यकता नहीं हो सकती है कि यह उसी धागे द्वारा जारी किया जाए जिसने यह दावा किया था (लेकिन, यदि नहीं, तो आपको सावधानीपूर्वक ट्रैक करना होगा कि वर्तमान में इसके लिए ज़िम्मेदारी किसकी है, बहुत कुछ आवंटित स्मृति की तरह)।
इसलिए, यदि आपके पास एक संसाधन के कई उदाहरण हैं (जैसे कि तीन टेप ड्राइव), तो आप 3. की गिनती के साथ एक सेमाफोर का उपयोग कर सकते हैं। ध्यान दें कि यह आपको यह नहीं बताता है कि आपके पास कौन से टेप ड्राइव हैं, बस एक निश्चित संख्या।
सेमाफोर के साथ, एक एकल लॉकर के लिए संसाधन के कई उदाहरणों को लॉक करना संभव है, जैसे टेप-टू-टेप कॉपी। यदि आपके पास एक संसाधन है (एक स्मृति स्थान है जिसे आप भ्रष्ट नहीं करना चाहते हैं), तो एक म्यूटेक्स अधिक उपयुक्त है।
समतुल्य संचालन हैं:
Counting semaphore Mutual exclusion semaphore
-------------------------- --------------------------
Claim/decrease (P) Lock
Release/increase (V) Unlock
एक तरफ: यदि आपने कभी भी विचित्र और दावा के लिए उपयोग किए जाने वाले विचित्र पत्रों पर आश्चर्य किया है, तो यह इसलिए था क्योंकि आविष्कारक डच था। प्रोबेर ते वर्लगेन का मतलब है कोशिश करना और घटाना जबकि वर्जन का मतलब बढ़ना है।
(ए) ... या इसे एक सेमाफोर से पूरी तरह से अलग कुछ के रूप में माना जा सकता है, जिसे उनके लगभग-हमेशा-अलग-अलग उपयोगों से सुरक्षित किया जा सकता है।
यह समझना बहुत महत्वपूर्ण है कि एक म्यूटेक्स गिनती 1 के साथ एक अर्धवृत्त नहीं है!
यही कारण है कि बाइनरी सेमाफोर्स जैसी चीजें हैं (जो कि गिनती 1 के साथ वास्तव में सेमाफोर हैं)।
म्यूटेक्स और बाइनरी-सेमाफोर के बीच का अंतर स्वामित्व का सिद्धांत है:
एक म्यूटेक्स को एक कार्य द्वारा अधिग्रहित किया जाता है और इसलिए इसे उसी कार्य द्वारा जारी किया जाना चाहिए। इससे बाइनरी सेमाफोर्स (एक्सीलेंस रिलीज़, पुनरावर्ती गतिरोध और प्राथमिकता उलटा) के साथ कई समस्याओं को ठीक करना संभव हो जाता है।
कैविएट: मैंने लिखा है "यह संभव बनाता है", अगर और कैसे इन समस्याओं को ठीक किया जाता है तो ओएस कार्यान्वयन तक।
क्योंकि म्यूटेक्स को एक ही कार्य द्वारा जारी किया जाना है, यह कार्यों के सिंक्रनाइज़ेशन के लिए बहुत अच्छा नहीं है। लेकिन अगर हालत चर के साथ संयुक्त आप आईपीसी आदिम के सभी प्रकार के निर्माण के लिए बहुत शक्तिशाली इमारत ब्लॉकों मिलता है।
इसलिए मेरी सिफारिश है: यदि आपको सफाई से लागू किए गए म्यूटेक्स और स्थिति चर (जैसे POSIX pthreads) इनका उपयोग करते हैं।
यदि आप जिस समस्या को हल करने की कोशिश कर रहे हैं, उसके ठीक विपरीत होने पर ही वे सेमाफोर का उपयोग करें, अन्य प्राइमेटिव बनाने की कोशिश न करें (जैसे कि सेमीफोर से आरडब्ल्यू-लॉक, इनके लिए म्यूटेक्स और कंडीशन वैरिएबल का उपयोग करें)
बहुत सारी गलतफहमी म्यूटेक्स और सेमाफोरस है। मुझे अब तक का सबसे अच्छा विवरण इस 3-भाग लेख में है:
म्यूटेक्स बनाम सेमाफोरस - भाग 1: सेमाफोरस
म्यूटेक्स बनाम सेमाफोरस - भाग 2: द म्यूटेक्स
म्यूटेक्स बनाम सेमाफोरस - भाग 3 (अंतिम भाग): पारस्परिक बहिष्करण समस्याएं
जबकि @opaxdiablo उत्तर पूरी तरह से सही है, मैं यह बताना चाहता हूं कि दोनों चीजों का उपयोग परिदृश्य काफी भिन्न है। म्यूटेक्स का उपयोग कोड के कुछ हिस्सों को समवर्ती रूप से चलाने के लिए किया जाता है, एक धागे को चलाने के लिए दूसरे धागे को संकेत करने के लिए सेमाफोर का उपयोग किया जाता है।
/* Task 1 */
pthread_mutex_lock(mutex_thing);
// Safely use shared resource
pthread_mutex_unlock(mutex_thing);
/* Task 2 */
pthread_mutex_lock(mutex_thing);
// Safely use shared resource
pthread_mutex_unlock(mutex_thing); // unlock mutex
सेमाफोर परिदृश्य अलग है:
/* Task 1 - Producer */
sema_post(&sem); // Send the signal
/* Task 2 - Consumer */
sema_wait(&sem); // Wait for signal
अधिक स्पष्टीकरण के लिए http://www.netrino.com/node/202 देखें
sema_wait
:-) मेरी राय में, वे दोनों संसाधनों के बारे में हैं और अन्य थ्रेड्स को सौंपी गई अधिसूचना एक साइड-इफेक्ट (बहुत महत्वपूर्ण, प्रदर्शन-वार) है सुरक्षा।
You say that the usage pattern of semaphores is to notify threads
धागे को सूचित करने के बारे में एक बिंदु। आप कॉल कर सकते हैं sem_post
एक संकेत हैंडलर सुरक्षित रूप से (से pubs.opengroup.org/onlinepubs/009695399/functions/... ) लेकिन यह कॉल करने के लिए सिफारिश नहीं है pthread_mutex_lock
और pthread_mutex_unlock
संकेत संचालकों से ( manpages.ubuntu.com/manpages/lucid/man3/... )
"टॉयलेट का उदाहरण" देखें - http://pheatt.emporia.edu/courses/2010/cs557f10/hand07/Mutex%20vs_%20Semaphore.htm :
म्युटेक्स:
शौचालय की चाबी है। उस समय एक व्यक्ति के पास शौचालय हो सकता है। समाप्त होने पर, व्यक्ति कतार में अगले व्यक्ति को कुंजी देता (मुक्त करता है)।
आधिकारिक तौर पर: "म्यूटेक्स का उपयोग आम तौर पर फिर से प्रवेश करने वाले कोड के एक खंड तक पहुंच को अनुक्रमित करने के लिए किया जाता है जिसे एक से अधिक थ्रेड द्वारा समवर्ती रूप से निष्पादित नहीं किया जा सकता है। म्यूटेक्स ऑब्जेक्ट केवल एक थ्रेड को नियंत्रित अनुभाग में अनुमति देता है, जिससे अन्य थ्रेड मजबूर होते हैं जो एक्सेस प्राप्त करने का प्रयास करते हैं। उस खंड तक इंतजार करना होगा जब तक कि पहला धागा उस खंड से बाहर नहीं निकल गया। " Ref: सिम्बियन डेवलपर लाइब्रेरी
(एक म्यूटेक्स वास्तव में मूल्य 1 के साथ एक सेमाफोर है)
सेमाफोर:
मुफ्त समान टॉयलेट कीज़ की संख्या है। उदाहरण के लिए, मान लें कि हमारे पास समान ताले और कुंजियों के साथ चार शौचालय हैं। सेमाफोर की गिनती - चाबियों की गिनती - शुरुआत में 4 पर सेट होती है (सभी चार शौचालय मुक्त होते हैं), फिर गिनती मूल्य में कमी आती है क्योंकि लोग अंदर आ रहे हैं। यदि सभी शौचालय पूर्ण हैं, अर्थात। कोई मुफ्त कुंजियाँ नहीं बची हैं, सेमाफोर की गिनती 0. अब, जब eq है। एक व्यक्ति शौचालय छोड़ देता है, सेमाफोर को 1 (एक मुफ्त कुंजी) तक बढ़ाया जाता है, और कतार में अगले व्यक्ति को दिया जाता है।
आधिकारिक तौर पर: "एक सेमीफ़ोर एक साझा संसाधन के एक साथ उपयोगकर्ताओं की संख्या को अधिकतम संख्या तक सीमित करता है। थ्रेड्स संसाधन (सेमीफ़ायर को घटाते हुए) तक पहुंच का अनुरोध कर सकते हैं, और संकेत दे सकते हैं कि उन्होंने संसाधन का उपयोग कर समाप्त कर दिया है (सेमीफ़ोर को बढ़ाते हुए)। " Ref: सिम्बियन डेवलपर लाइब्रेरी
ज़नी ध्वनि नहीं करने की कोशिश कर रहा है, लेकिन खुद को मदद नहीं कर सकता।
आपका सवाल यह होना चाहिए कि म्यूटेक्स और सेमाफोरस में क्या अंतर है? और अधिक सटीक सवाल होना चाहिए, 'म्यूटेक्स और सेमाफोरस के बीच क्या संबंध है?'
(मैंने उस सवाल को जोड़ा होगा, लेकिन मुझे यकीन है कि कुछ सौन्दर्यपूर्ण मध्यस्थ कुछ अंतर और संबंध के बीच अंतर को समझे बिना इसे डुप्लिकेट के रूप में बंद कर देंगे।)
वस्तु शब्दावली में हम यह देख सकते हैं कि:
अवलोकन। 1 सेमाफोर में म्यूटेक्स होता है
ओवल्यूशन ।2 म्यूटेक्स सेमीफोर नहीं है और सेमीफोर म्यूटेक्स नहीं है।
कुछ सेमाफोर हैं जो म्यूटेक्स के रूप में कार्य करेंगे, जिन्हें बाइनरी सेमाफोर कहा जाता है, लेकिन वे मूक नहीं हो रहे हैं।
सिग्नलिंग नामक एक विशेष घटक है (पॉज़िक्स उस नाम के लिए condition_variable का उपयोग करता है), जिसे mxx से एक सेमाफोर बनाने के लिए आवश्यक है। इसे अधिसूचना-स्रोत के रूप में सोचें। यदि दो या अधिक थ्रेड्स को एक ही सूचना-स्रोत के लिए सब्सक्राइब किया जाता है, तो उन्हें जागने के लिए एक या सभी को संदेश भेजना संभव है।
सेमाफोर से जुड़े एक या अधिक काउंटर हो सकते हैं, जो म्यूटेक्स द्वारा संरक्षित हैं। सेमाफोर के लिए सबसे सरल परिदृश्य, एक एकल काउंटर है जो 0 या 1 हो सकता है।
यह वह जगह है जहां भ्रम मानसून की बारिश की तरह होता है।
एक काउंटर के साथ एक अर्धवृत्त जो 0 या 1 हो सकता है, म्यूटेक्स नहीं है।
म्यूटेक्स के दो राज्य (0,1) और एक स्वामित्व (कार्य) है। सेमफोर में एक म्यूटेक्स, कुछ काउंटर और एक स्थिति चर है।
अब, अपनी कल्पना का उपयोग करें, और काउंटर के उपयोग के हर संयोजन और जब संकेत करने के लिए एक तरह का सेमीफोर बना सकते हैं।
मान 0 या 1 और सिग्नलिंग के साथ सिंगल काउंटर जब वैल्यू 1 पर जाता है और तब सिग्नल पर प्रतीक्षा करने वाले व्यक्ति में से एक को अनलॉक करता है == बाइनरी सेमर
मान 0 से N तक सिंगल काउंटर और जब N से मान कम होता है, तब सिग्नलिंग होता है और मान N == सेमाफोर की गणना करते समय लॉक / वेट करता है
मान 0 से N के लिए सिंगल काउंटर और जब मान N पर जाता है और सिग्नलिंग करता है, और मान N == बैरियर सेमाफोर से कम होने पर लॉक / वेट करता है (अच्छी तरह से अगर वे इसे कॉल नहीं करते हैं, तो उन्हें करना चाहिए।)
अब आपके सवाल पर कि कब क्या उपयोग करना है। (या म्यूटेक्स का उपयोग करते समय या जब आप बाइनरी-सेमाफोर का उपयोग नहीं करते हैं, तो गैर-बाइनरी-सेमाफोर की तुलना नहीं की जाती है, तब सही प्रश्न संस्करण। 3) जब आप 1. एक स्वनिर्धारित व्यवहार चाहते हैं, तो म्यूटेक्स का उपयोग करें। सेमाफोर, जैसे स्पिन-लॉक या फास्ट-लॉक या पुनरावर्ती-लॉक हैं। आप आमतौर पर म्यूटेक्स को विशेषताओं के साथ कस्टमाइज़ कर सकते हैं, लेकिन सेमीफ़ायर को कस्टमाइज़ करना नया सेमीफ़ोर लिखने के अलावा और कुछ नहीं है। 2. आप हल्के या तेज आदिम चाहते हैं
सेमाफोर का उपयोग करें, जब आप जो चाहते हैं वह वास्तव में इसके द्वारा प्रदान किया जाता है।
यदि आप नहीं समझते हैं कि बाइनरी-सेमाफोर के आपके कार्यान्वयन द्वारा क्या प्रदान किया जा रहा है, तो IMHO, म्यूटेक्स का उपयोग करें।
और अंत में सिर्फ SO पर निर्भर होने के बजाय एक किताब पढ़ें।
मुझे लगता है कि प्रश्न म्यूटेक्स और बाइनरी सेमाफोर के बीच अंतर होना चाहिए।
म्यूटेक्स = यह एक स्वामित्व लॉक तंत्र है, केवल थ्रेड जो ताला प्राप्त करता है, वह लॉक को मुक्त कर सकता है।
बाइनरी सेमाफोर = यह एक सिग्नल तंत्र के अधिक है, यदि कोई अन्य उच्च प्राथमिकता वाला धागा है तो वह सिग्नल और लॉक ले सकता है।
Mutex साझा संसाधन की सुरक्षा करना है।
सेमाफोर धागों को भेजने के लिए है।
म्यूटेक्स:
कल्पना करें कि बेचने के लिए कुछ टिकट हैं। हम एक ऐसे मामले का अनुकरण कर सकते हैं जहां कई लोग एक ही समय में टिकट खरीदते हैं: प्रत्येक व्यक्ति टिकट खरीदने के लिए एक धागा है। जाहिर है हमें टिकटों की सुरक्षा के लिए म्यूटेक्स का उपयोग करने की आवश्यकता है क्योंकि यह साझा संसाधन है।
सेमाफोर:
कल्पना करें कि हमें नीचे के रूप में एक गणना करने की आवश्यकता है:
c = a + b;
इसके अलावा, हमें geta()
गणना करने के लिए एक फ़ंक्शन a
, गणना करने के लिए एक फ़ंक्शन getb()
और गणना करने के लिए b
एक फ़ंक्शन getc()
की आवश्यकता है c = a + b
।
जाहिर है, हम नहीं कर सकते c = a + b
जब तक कि geta()
और getb()
समाप्त हो गया है।
यदि तीन कार्य तीन थ्रेड हैं, तो हमें तीन थ्रेड प्रेषण करने की आवश्यकता है।
int a, b, c;
void geta()
{
a = calculatea();
semaphore_increase();
}
void getb()
{
b = calculateb();
semaphore_increase();
}
void getc()
{
semaphore_decrease();
semaphore_decrease();
c = a + b;
}
t1 = thread_create(geta);
t2 = thread_create(getb);
t3 = thread_create(getc);
thread_join(t3);
सेमाफोर की मदद से, ऊपर दिए गए कोड से यह सुनिश्चित किया जा सकता है कि t3
यह अपना काम पूरा नहीं करेगा t1
और t2
अपने काम किए होंगे।
एक शब्द में, सेमाफोर थ्रेड को एक लॉजिकल ऑर्डर के रूप में निष्पादित करना है जबकि म्यूटेक्स साझा संसाधन की रक्षा करना है।
इसलिए वे एक ही बात नहीं हैं भले ही कुछ लोग हमेशा कहते हैं कि म्यूटेक्स शुरुआती मूल्य के साथ एक विशेष सेमाफोर है। आप इस तरह भी कह सकते हैं, लेकिन कृपया ध्यान दें कि वे विभिन्न मामलों में उपयोग किए जाते हैं। यदि आप ऐसा कर सकते हैं तो भी एक दूसरे को प्रतिस्थापित न करें।
x = getx(); y = gety(); z = x + y;
किसी कारण के लिए, हम तीन धागे तीन काम करने के लिए उपयोग करते हैं, अब धागे के आदेश क्योंकि हम ऐसा नहीं कर सकते बहुत महत्वपूर्ण है x + y
जब तक getx
और gety
समाप्त कर दिया है। एक शब्द में, सेमाफोर का उपयोग तब किया जाता है जब हम बहु-थ्रेडिंग के निष्पादन के क्रम की परवाह करते हैं।
x
और y
पूरा हो जाए, फिर गणना करें z = x + y
। मुझे पता है जावा है CyclicBarrier
। इसके अलावा, मुझे यकीन नहीं है कि अगर मैं कह सकता हूं कि mapreduce
यह सेमाफोर यूसेज़ भी है, क्योंकि मैं reduce
तब तक नहीं कर सकता जब तक सभी map
एस पूरा नहीं हो जाते।
उपरोक्त सभी उत्तर अच्छी गुणवत्ता के हैं, लेकिन यह एक memorize.The नाम करने के लिए बस है Mutex से प्राप्त होता है परस्पर अनन्य इसलिए यदि आप एक समय में केवल एक के रूप में दोनों के बीच पारस्परिक अपवर्जन के रूप में एक म्युटेक्स ताला के बारे में सोचना प्रेरित होते हैं, और अगर मैं यह पास तुम्हारे पास कर सकते हैं के बाद ही मैं it.On जारी दूसरी ओर इस तरह के मामले के लिए मौजूद नहीं है सेमाफोर सिर्फ एक यातायात संकेत की तरह (जो शब्द सेमाफोर भी साधन) है।
जैसा कि बताया गया था, एक की गिनती के साथ एक सेमाफोर 'बाइनरी' सेमाफोर के समान है जो म्यूटेक्स के समान है।
मुख्य चीजें जो मैंने सेमीफोरर्स देखी हैं, जिनके लिए उपयोग की जाने वाली गिनती से अधिक निर्माता / उपभोक्ता स्थितियों में आपके पास एक निश्चित निश्चित आकार की एक कतार है।
आपके पास दो सेमाफोर हैं। पहले सेमाफोर को शुरू में कतार में वस्तुओं की संख्या के लिए सेट किया जाता है और दूसरे सेमाफोर को 0. पर सेट किया जाता है। निर्माता पहले सेमीफोर पर एक पी ऑपरेशन करता है, कतार में जोड़ता है। और दूसरे पर V ऑपरेशन करता है। उपभोक्ता दूसरे सेमाफोर पर एक पी ऑपरेशन करता है, कतार से हटाता है, और फिर पहले पर एक वी ऑपरेशन करता है।
इस तरह जब भी कतार भरती है तो निर्माता अवरुद्ध हो जाता है, और जब भी कतार खाली होती है, तो उपभोक्ता अवरुद्ध हो जाता है।
एक म्यूटेक्स एक सेमाफोर का एक विशेष मामला है। एक सेमाफोर कई धागे को महत्वपूर्ण खंड में जाने की अनुमति देता है। एक सेमाफोर बनाते समय आप परिभाषित करते हैं कि महत्वपूर्ण खंड में थ्रेड्स की अनुमति कैसे हो सकती है। बेशक आपका कोड इस महत्वपूर्ण अनुभाग तक कई पहुंच को संभालने में सक्षम होना चाहिए।
बाइनरी सेमाफोर और म्यूटेक्स अलग हैं। ओएस के दृष्टिकोण से, एक बाइनरी सेमाफोर और काउंटिंग सेमाफोर को एक ही तरीके से लागू किया जाता है और एक बाइनरी सेमाफोर का मान 0 या 1 हो सकता है।
म्यूटेक्स -> कोड के एक महत्वपूर्ण खंड के लिए केवल और केवल एक ही उद्देश्य के लिए इस्तेमाल किया जा सकता है।
सेमफोर -> विभिन्न समस्याओं को हल करने के लिए इस्तेमाल किया जा सकता है। एक बाइनरी सेमाफोर का उपयोग सिग्नलिंग के लिए किया जा सकता है और आपसी बहिष्करण समस्या को भी हल कर सकता है। जब 0 से प्रारंभ किया जाता है , तो यह सिग्नलिंग समस्या को हल करता है और जब इसे 1 से प्रारंभ किया जाता है , तो यह पारस्परिक अपवर्जन समस्या को हल करता है।
जब संसाधनों की संख्या अधिक होती है और उन्हें सिंक्रनाइज़ करने की आवश्यकता होती है, तो हम गिनती का उपयोग कर सकते हैं।
अपने ब्लॉग में, मैंने इन विषयों पर विस्तार से चर्चा की है।
https://designpatterns-oo-cplusplus.blogspot.com/2015/07/synchronization-primitives-mutex-and.html