म्यूटेक्स उदाहरण / ट्यूटोरियल? [बन्द है]


176

मैं मल्टीथ्रेडिंग में नया हूं, और यह समझने की कोशिश कर रहा हूं कि म्यूटेक्स कैसे काम करता है। बहुत सारे Googling किए लेकिन यह अभी भी कुछ संदेह है कि यह कैसे काम करता है क्योंकि मैंने अपना कार्यक्रम बनाया जिसमें लॉकिंग काम नहीं किया।

म्यूटेक्स का एक बिल्कुल गैर-सहज वाक्यविन्यास है pthread_mutex_lock( &mutex1 );, जहां ऐसा लगता है कि म्यूटेक्स लॉक हो रहा है, जब मैं वास्तव में लॉक करना चाहता हूं तो कुछ अन्य चर है। क्या इस वाक्यविन्यास का अर्थ है कि म्यूटेक्स को लॉक करना कोड के एक क्षेत्र को लॉक करता है जब तक कि म्यूटेक्स अनलॉक नहीं हो जाता है? फिर थ्रेड्स कैसे जानते हैं कि क्षेत्र लॉक है? [ अद्यतन: सूत्र जानते हैं कि यह क्षेत्र मेमोरी फ़ेंसिंग द्वारा लॉक किया गया है ]। और क्या ऐसी घटना को महत्वपूर्ण धारा नहीं कहा जाना चाहिए? [ अद्यतन: महत्वपूर्ण खंड ऑब्जेक्ट्स केवल विंडोज में उपलब्ध हैं, जहां ऑब्जेक्ट म्यूटेक्स की तुलना में तेज़ हैं और केवल उस थ्रेड को दिखाई देते हैं जो इसे लागू करता है। अन्यथा, महत्वपूर्ण खंड सिर्फ एक म्यूटेक्स द्वारा संरक्षित कोड के क्षेत्र को संदर्भित करता है ]

संक्षेप में, क्या आप सरलतम संभव म्यूटेक्स उदाहरण कार्यक्रम और यह कैसे काम करता है के तर्क पर सबसे सरल संभव स्पष्टीकरण के साथ मदद कर सकता है ? मुझे यकीन है कि इस वसीयत मदद कर रहा हूँ बहुत सारे अन्य newbies की।


2
एक सरल ट्यूटोरियल की आवश्यकता पर जोर देना जारी रखें (यह थ्रेड्स, tbb या pthreads को बढ़ावा दें): भ्रम के उदाहरण: 1. stackoverflow.com/questions/3528877/… 2. 2. stackoverflow.com/questions/2979525/… 3। stackoverflow.com/questions/2095977/to-mutex-or-not-to-mutex 4. stackoverflow.com/questions/3931026/… 5. 5. stackoverflow.com/questions/1525189-…
नव

1
मुझे इससे कोई आपत्ति नहीं है, लेकिन आपकी अंतिम टिप्पणी मुझे जो बताती है, वह यह है कि हमें म्यूटेक्स कैसे काम करता है और हमें उनकी आवश्यकता क्यों है, इसके बारे में कम सादृश्यता और बेहतर तकनीकी व्याख्या की आवश्यकता है।
सैन जैसिंटो

@ शान: कोई अपराध नहीं हुआ :) मेरी टिप्पणी केवल यह सुझाव देने के लिए थी कि एक नौसिखिया म्यूटेक्स का सबसे छोटा, स्पष्ट विवरण प्राप्त कर सकता है। कई एनालॉग्स नौसिखिया के लिए भ्रमित हो सकते हैं, इसलिए अलग-अलग एनालॉग्स को अलग-अलग रखा जाना चाहिए। मेरे लिए ques और ans पोस्ट करने का पूरा कारण एक नौसिखिया के रूप में है, मुझे इसे लंबे स्पष्टीकरण और कोड नमूनों के माध्यम से पढ़ने में दर्द हुआ। मैं नहीं चाहूंगा कि किसी और को दर्द से गुजरना पड़े।
नव

2
@ नीति: यदि इस उत्तर को बेहतर बनाया जा सकता है, तो मुझे आपके सुझाव लेने में खुशी होगी। मुझे बस खुशी है कि बहुत से अन्य लोगों ने इसे मददगार पाया है। यदि यह आपकी मदद नहीं करता है, तो अन्य लोगों के उत्तर भी हैं जिन्होंने अन्य म्यूटेक्स ट्यूटोरियल की ओर इशारा किया है। इतना नकारात्मक क्यों हो?
नव

जवाबों:


278

यहाँ दुनिया भर के newbies को अवधारणा को समझाने का मेरा विनम्र प्रयास है: ( मेरे ब्लॉग पर एक रंग कोडित संस्करण )

बहुत से लोग अपने प्रियजनों से बात करने के लिए एक अकेला फोन बूथ चलाते हैं (उनके पास मोबाइल फोन नहीं है)। बूथ के दरवाज़े के हैंडल को पकड़ने वाला पहला व्यक्ति, वह है जिसे फोन का उपयोग करने की अनुमति है। जब तक वह फोन का उपयोग करता है, तब तक उसे दरवाजे के हैंडल पर पकड़ कर रखना पड़ता है, अन्यथा कोई अन्य व्यक्ति हैंडल को पकड़ लेगा, उसे बाहर फेंक देगा और अपनी पत्नी से बात करेगा :) ऐसी कोई कतार प्रणाली नहीं है। जब व्यक्ति अपनी कॉल समाप्त करता है, तो बूथ से बाहर आता है और दरवाज़े के हैंडल को छोड़ देता है, अगले व्यक्ति को दरवाज़े के हैंडल को पकड़कर फोन का उपयोग करने की अनुमति होगी।

एक धागा है: प्रत्येक व्यक्ति म्युटेक्स है: दरवाजा संभाल ताला है: व्यक्ति के हाथ संसाधन है: फोन


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

एक बार जब थ्रेड ने उस कोड को निष्पादित कर लिया है, तो उसे म्यूटेक्स पर लॉक को छोड़ देना चाहिए ताकि एक और धागा म्यूटेक्स पर लॉक हासिल कर सके (अन्य लोग जो फोन बूथ तक पहुंचने में सक्षम हैं)।

[ एक म्यूटेक्स होने की अवधारणा वास्तविक-दुनिया की अनन्य पहुंच पर विचार करते समय थोड़ी बेतुकी है, लेकिन प्रोग्रामिंग दुनिया में मुझे लगता है कि अन्य थ्रेड्स को देखने के लिए कोई अन्य तरीका नहीं था कि एक धागा पहले से ही कोड की कुछ पंक्तियों को निष्पादित कर रहा था। पुनरावर्ती म्यूटेक्स आदि की अवधारणाएं हैं, लेकिन यह उदाहरण केवल आपको मूल अवधारणा दिखाने के लिए था। आशा है कि उदाहरण आपको अवधारणा की स्पष्ट तस्वीर देगा। ]

C ++ 11 सूत्रण के साथ:

#include <iostream>
#include <thread>
#include <mutex>

std::mutex m;//you can use std::lock_guard if you want to be exception safe
int i = 0;

void makeACallFromPhoneBooth() 
{
    m.lock();//man gets a hold of the phone booth door and locks it. The other men wait outside
      //man happily talks to his wife from now....
      std::cout << i << " Hello Wife" << std::endl;
      i++;//no other thread can access variable i until m.unlock() is called
      //...until now, with no interruption from other men
    m.unlock();//man lets go of the door handle and unlocks the door
}

int main() 
{
    //This is the main crowd of people uninterested in making a phone call

    //man1 leaves the crowd to go to the phone booth
    std::thread man1(makeACallFromPhoneBooth);
    //Although man2 appears to start second, there's a good chance he might
    //reach the phone booth before man1
    std::thread man2(makeACallFromPhoneBooth);
    //And hey, man3 also joined the race to the booth
    std::thread man3(makeACallFromPhoneBooth);

    man1.join();//man1 finished his phone call and joins the crowd
    man2.join();//man2 finished his phone call and joins the crowd
    man3.join();//man3 finished his phone call and joins the crowd
    return 0;
}

संकलन करें और उपयोग करें g++ -std=c++0x -pthread -o thread thread.cpp;./thread

स्पष्ट रूप से उपयोग करने के बजाय lockऔर unlock, आप यहां दिखाए गए अनुसार कोष्ठक का उपयोग कर सकते हैं , यदि आप इसके लाभ के लिए एक स्कोप लॉक का उपयोग कर रहे हैं । स्कोप किए गए तालों के ऊपर थोड़ा सा प्रदर्शन होता है।


2
@ शान: मैं ईमानदार रहूँगा; हां मुझे यह तथ्य पसंद है कि आपने पूरी तरह से नौसिखियों को विवरण (प्रवाह के साथ) समझाने की पूरी कोशिश की है। लेकिन, (कृपया मुझे गलत न समझें) इस पोस्ट का उद्देश्य अवधारणा को एक छोटी व्याख्या में रखा गया था (लंबे ट्यूटोरियल के लिए दिए गए अन्य उत्तर)। मुझे आशा है कि यदि आप अपने संपूर्ण उत्तर की प्रतिलिपि बनाने और इसे एक अलग उत्तर के रूप में पोस्ट करने का अनुरोध करते हैं तो आपको कोई आपत्ति नहीं होगी? ताकि मैं आपके उत्तर को इंगित करने के लिए रोलबैक करूं और संपादित कर सकूं।
नव

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

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

8
आपका C ++ 11 का उदाहरण गलत है । तो क्या टीबीबी एक है, सुराग स्कॉप्ड लॉक के नाम पर है ।
जोनाथन वेकली

3
मुझे @ जनाथन दोनों के बारे में अच्छी तरह से पता है। आपको लग रहा था कि मैंने जो वाक्य लिखा था, वह छूट गया (could've shown scoped locking by not using acquire and release - which also is exception safe -, but this is clearer। स्कोप लॉकिंग का उपयोग करने के लिए, यह डेवलपर पर निर्भर है कि वे किस तरह के एप्लिकेशन का निर्माण कर रहे हैं। यह उत्तर म्यूटेक्स अवधारणा की बुनियादी समझ को संबोधित करने और इसके सभी जटिलताओं में नहीं आने के लिए था, इसलिए आपकी टिप्पणियों और लिंक का स्वागत है लेकिन इस ट्यूटोरियल के दायरे से बाहर है।
नव

41

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

//somewhere long ago, we have i declared as int
void my_concurrently_called_function()
{
  i++;
}

इस फ़ंक्शन के इंटर्नल्स बहुत सरल दिखते हैं। यह केवल एक बयान है। हालाँकि, एक सामान्य छद्म विधानसभा भाषा समकक्ष हो सकती है:

load i from memory into a register
add 1 to i
store i back into memory

क्योंकि समतुल्य असेंबली-भाषा निर्देश सभी के लिए irement ऑपरेशन करने के लिए आवश्यक हैं, हम कहते हैं कि incrementing i एक गैर-atmoic ऑपरेशन है। एक परमाणु ऑपरेशन वह है जिसे निर्देश निष्पादन शुरू होने के बाद एक बार बाधित नहीं होने के गुरंट्टी के साथ हार्डवेयर पर पूरा किया जा सकता है। वृद्धि में 3 परमाणु निर्देशों की एक श्रृंखला शामिल है। एक समवर्ती प्रणाली में जहां कई थ्रेड्स फ़ंक्शन को बुला रहे हैं, समस्या तब उत्पन्न होती है जब कोई थ्रेड गलत समय पर पढ़ता या लिखता है। कल्पना करें कि हमारे पास एक साथ चलने वाले दो धागे हैं और एक दूसरे के तुरंत बाद फ़ंक्शन को कॉल करता है। हम यह भी कहते हैं कि हमने 0. को इनिशियलाइज़ किया है। यह भी मान लें कि हमारे पास बहुत सारे रजिस्टर हैं और यह कि दो धागे पूरी तरह से अलग रजिस्टरों का उपयोग कर रहे हैं, इसलिए कोई टकराव नहीं होगा। इन घटनाओं का वास्तविक समय हो सकता है:

thread 1 load 0 into register from memory corresponding to i //register is currently 0
thread 1 add 1 to a register //register is now 1, but not memory is 0
thread 2 load 0 into register from memory corresponding to i
thread 2 add 1 to a register //register is now 1, but not memory is 0
thread 1 write register to memory //memory is now 1
thread 2 write register to memory //memory is now 1

क्या हुआ है कि हमारे पास दो सूत्र हैं जो कि मैं समवर्ती रूप से बढ़ाता हूं, हमारे कार्य को दो बार कहा जाता है, लेकिन परिणाम उस तथ्य के साथ असंगत है। ऐसा लगता है कि फ़ंक्शन केवल एक बार बुलाया गया था। ऐसा इसलिए है क्योंकि मशीन स्तर पर परमाणु "टूट" गया है, जिसका अर्थ है कि धागे एक-दूसरे को बाधित कर सकते हैं या गलत समय पर एक साथ काम कर सकते हैं।

हमें इसे हल करने के लिए एक तंत्र की आवश्यकता है। हमें ऊपर दिए गए निर्देशों को कुछ आदेश देने की आवश्यकता है। एक सामान्य तंत्र एक को छोड़कर सभी थ्रेड्स को ब्लॉक करना है। Pthread mutex इस तंत्र का उपयोग करता है।

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

एक बार जब थ्रेड महत्वपूर्ण खंड को निष्पादित कर लेता है, तो उसे म्यूटेक्स पर लॉक को छोड़ देना चाहिए ताकि एक और धागा म्यूटेक्स पर लॉक प्राप्त कर सके।

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

तो तकनीकी रूप से, एक म्यूटेक्स कैसे काम करता है? क्या यह उसी दौड़ की स्थिति से ग्रस्त नहीं है जिसका हमने पहले उल्लेख किया था? क्या pthread_mutex_lock () थोड़ा अधिक जटिल है जो एक चर का एक साधारण वेतन वृद्धि है?

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

नोट: कुछ खंड पहले के उत्तर के समान दिखाई दे सकते हैं। मैंने संपादित करने के लिए उनके निमंत्रण को स्वीकार किया, उन्होंने मूल तरीका पसंद किया, इसलिए मैं वही रख रहा हूं जो मेरे पास था, जो कि उनके क्रिया-कलापों से थोड़ा प्रभावित है।


1
बहुत बहुत धन्यवाद, सैन। मैं आपके उत्तर से जुड़ा हुआ हूं :) वास्तव में, मैंने इरादा किया था कि आप मेरा उत्तर लें + अपना उत्तर दें और प्रवाह को बनाए रखने के लिए इसे एक अलग उत्तर के रूप में पोस्ट करें। यदि आप मेरे उत्तर के किसी भी भाग का पुनः उपयोग करते हैं तो मुझे वास्तव में कोई आपत्ति नहीं है। हम वैसे भी खुद के लिए ऐसा नहीं कर रहे हैं।
नव

13

सबसे अच्छा थ्रेड ट्यूटोरियल जो मैं यहाँ जानता हूँ:

https://computing.llnl.gov/tutorials/pthreads/

मुझे यह पसंद है कि यह एक विशेष कार्यान्वयन के बजाय एपीआई के बारे में लिखा गया है, और यह आपको सिंक्रनाइज़ेशन को समझने में मदद करने के लिए कुछ अच्छे सरल उदाहरण देता है।


मैं मानता हूं कि यह निश्चित रूप से एक अच्छा ट्यूटोरियल है, लेकिन यह एक पृष्ठ पर बहुत सारी जानकारी है और कार्यक्रम लंबे हैं। मैंने जो प्रश्न पोस्ट किया है वह "मेरे पास एक सपना है" भाषण का म्यूटेक्स संस्करण है, जहां न्यूबाइट्स म्यूटेक्स के बारे में जानने और समझने के लिए एक सरल तरीका ढूंढेंगे कि गैर-सहज ज्ञान युक्त वाक्यविन्यास कैसे काम करता है (यह एक व्याख्या है जो सभी ट्यूटोरियल में कमी है) ।
नव

7

मैं हाल ही में इस पद पर ठोकर खाई और लगता है कि इसे मानक पुस्तकालय के c ++ 11 mutex (अर्थात् std :: mutex) के लिए एक अद्यतन समाधान की आवश्यकता है।

मैंने नीचे कुछ कोड चिपकाया है (एक म्यूटेक्स के साथ मेरे पहले कदम - मैंने हेंडले, सेटएवेंट, वेटफॉरमेल्टऑउटऑब्जेक्ट्स आदि के साथ win32 पर संगामिति सीखी)।

चूंकि यह std :: mutex और दोस्तों के साथ मेरा पहला प्रयास है, मुझे टिप्पणियाँ, सुझाव और सुधार देखना अच्छा लगेगा!

#include <condition_variable>
#include <mutex>
#include <algorithm>
#include <thread>
#include <queue>
#include <chrono>
#include <iostream>


int _tmain(int argc, _TCHAR* argv[])
{   
    // these vars are shared among the following threads
    std::queue<unsigned int>    nNumbers;

    std::mutex                  mtxQueue;
    std::condition_variable     cvQueue;
    bool                        m_bQueueLocked = false;

    std::mutex                  mtxQuit;
    std::condition_variable     cvQuit;
    bool                        m_bQuit = false;


    std::thread thrQuit(
        [&]()
        {
            using namespace std;            

            this_thread::sleep_for(chrono::seconds(5));

            // set event by setting the bool variable to true
            // then notifying via the condition variable
            m_bQuit = true;
            cvQuit.notify_all();
        }
    );


    std::thread thrProducer(
        [&]()
        {
            using namespace std;

            int nNum = 13;
            unique_lock<mutex> lock( mtxQuit );

            while ( ! m_bQuit )
            {
                while( cvQuit.wait_for( lock, chrono::milliseconds(75) ) == cv_status::timeout )
                {
                    nNum = nNum + 13 / 2;

                    unique_lock<mutex> qLock(mtxQueue);
                    cout << "Produced: " << nNum << "\n";
                    nNumbers.push( nNum );
                }
            }
        }   
    );

    std::thread thrConsumer(
        [&]()
        {
            using namespace std;
            unique_lock<mutex> lock(mtxQuit);

            while( cvQuit.wait_for(lock, chrono::milliseconds(150)) == cv_status::timeout )
            {
                unique_lock<mutex> qLock(mtxQueue);
                if( nNumbers.size() > 0 )
                {
                    cout << "Consumed: " << nNumbers.front() << "\n";
                    nNumbers.pop();
                }               
            }
        }
    );

    thrQuit.join();
    thrProducer.join();
    thrConsumer.join();

    return 0;
}

1
उत्तम! पोस्ट करने का शुक्रिया। हालांकि जैसा कि मैंने उल्लेख किया है कि मेरा उद्देश्य केवल एक म्यूटेक्स की अवधारणा को स्पष्ट करना था। अन्य सभी ट्यूटोरियल्स ने निर्माता उपभोक्ता और कंडीशन वैरिएबल आदि की अवधारणाओं के साथ इसे बहुत मुश्किल बना दिया, जिससे मेरे लिए यह समझना बहुत मुश्किल हो गया कि पृथ्वी पर क्या चल रहा था।
नव

4

फ़ंक्शन pthread_mutex_lock()या तो कॉलिंग थ्रेड के लिए म्यूटेक्स प्राप्त करता है या थ्रेड को ब्लॉक करता है जब तक कि म्यूटेक्स का अधिग्रहण नहीं किया जा सकता है। संबंधित pthread_mutex_unlock()म्यूटेक्स जारी करता है।

म्यूटेक्स को एक कतार के रूप में सोचो; म्यूटेक्स को प्राप्त करने का प्रयास करने वाले प्रत्येक धागे को कतार के अंत में रखा जाएगा। जब एक धागा म्यूटेक्स को छोड़ता है, तो कतार में अगला धागा बंद हो जाता है और अब चल रहा है।

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


1
क्या यह गारंटी है कि वास्तव में अगला प्रयास धागा दर्ज करेगा?
आर्सेन मकर्चयन

1
@ कोई गारंटी नहीं। यह सिर्फ एक सहायक उपमा है।
क्रिसचॉक

3

आप म्यूटेक्स द्वारा संरक्षित क्षेत्र का उपयोग करने से पहले म्यूटेक्स चर की जांच करने वाले हैं। इसलिए आपका pthread_mutex_lock () क्रियान्वयन के आधार पर (mutex1 जारी होने तक) प्रतीक्षा कर सकता है या एक मान लौटा सकता है जो दर्शाता है कि ताला प्राप्त नहीं किया जा सकता है यदि कोई अन्य व्यक्ति पहले से ही इसे बंद कर चुका है।

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


1
pthread_mutex_lockयदि कोई अन्य व्यक्ति ताला लगाता है तो वापस नहीं लौट सकता। यह इस मामले में ब्लॉक करता है और यही पूरा बिंदु है। pthread_mutex_trylockवह फ़ंक्शन है जो लॉक होने पर वापस आ जाएगा।
आर .. गिटहब स्टॉप हेल्पिंग ICE

1
हाँ, मुझे पहले यह एहसास नहीं था कि यह किस तरह का कार्यान्वयन है।
मकिस

3

शॉर्टेक्स म्यूटेक्स उदाहरण की तलाश करने वालों के लिए:

#include <mutex>

int main() {
    std::mutex m;

    m.lock();
    // do thread-safe stuff
    m.unlock();
}

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.