क्या बाइनरी सेमाफोर और म्यूटेक्स के बीच कोई अंतर है या क्या वे अनिवार्य रूप से समान हैं?
क्या बाइनरी सेमाफोर और म्यूटेक्स के बीच कोई अंतर है या क्या वे अनिवार्य रूप से समान हैं?
जवाबों:
वे एक ही बात नहीं कर रहे हैं । उनका उपयोग विभिन्न उद्देश्यों के लिए किया जाता है!
जबकि दोनों प्रकार के सेमाफोर में पूर्ण / खाली अवस्था होती है और एक ही एपीआई का उपयोग होता है, उनका उपयोग बहुत अलग होता है।
म्यूचुअल एक्सक्लूज़न सेमीफ़ोर्स
म्यूचुअल एक्सफ़ोलिएशन सेमीफ़ोर्स का उपयोग साझा संसाधनों (डेटा संरचना, फ़ाइल, आदि) की सुरक्षा के लिए किया जाता है।
एक म्यूटेक्स सेमाफोर उस कार्य के "स्वामित्व" है जो इसे लेता है। यदि टास्क बी टास्क ए द्वारा वर्तमान में आयोजित म्यूटेक्स को सेगिव करने का प्रयास करता है, तो टास्क बी का कॉल एक त्रुटि लौटाएगा और विफल हो जाएगा।
म्यूटेक्स हमेशा निम्नलिखित अनुक्रम का उपयोग करते हैं:
- सेमटेक - महत्वपूर्ण अनुभाग - सेमगिव
ये रहा एक सरल उदाहरण:
थ्रेड ए थ्रेड बी म्यूटेक्स को लें एक्सेस्स डेटा ... म्यूटेक्स ले लो <== ब्लॉक करेगा ... म्यूटेक्स एक्सेस डेटा दें <== अनब्लॉक करें ... म्यूटेक्स दें
बाइनरी सेमाफोर
बाइनरी सेमाफोर पूरी तरह से एक अलग सवाल है:
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
ध्यान दें कि एक बाइनरी सेमाफोर के साथ, बी के लिए सेमफोर और ए को देने के लिए ठीक है।
फिर, एक बाइनरी सेमाफोर एक संसाधन को पहुंच से नहीं बचा रहा है। गिविंग ऐंड टेकिंग ऑफ ए सेमाफोर मौलिक रूप से डिकॉप्ड है।
यह आमतौर पर एक ही कार्य के लिए एक ही बाइनरी सेमाफोर पर एक साथ देने और लेने के लिए बहुत कम समझ में आता है।
इसलिए निर्माता-उपभोक्ता जैसी कुछ सिंक्रनाइज़ेशन समस्याओं के लिए सेमाफोर अधिक उपयुक्त हैं।
विंडोज पर, बाइनरी सेमाफोर म्यूटेक्स की तुलना में इवेंट ऑब्जेक्ट की तरह अधिक हैं।
Mutex can be released only by thread that had acquired it
- मैं सिर्फ एक साधारण pthread_mutex आधारित कार्यक्रम के साथ कोशिश की, एक धागा मुख्य धागा में बंद mutex अनलॉक कर सकते हैं
शौचालय का उदाहरण एक आनंददायक सादृश्य है:
म्युटेक्स:
शौचालय की चाबी है। उस समय एक व्यक्ति के पास शौचालय हो सकता है। समाप्त होने पर, व्यक्ति कतार में अगले व्यक्ति को कुंजी देता (मुक्त करता है)।
आधिकारिक तौर पर: "म्यूटेक्स का उपयोग आम तौर पर फिर से प्रवेश करने वाले कोड के एक खंड तक पहुंच को अनुक्रमित करने के लिए किया जाता है जिसे एक से अधिक थ्रेड द्वारा समवर्ती रूप से निष्पादित नहीं किया जा सकता है। एक म्यूटेक्स ऑब्जेक्ट केवल एक थ्रेड को नियंत्रित अनुभाग में अनुमति देता है, जिससे अन्य थ्रेड मजबूर होते हैं जो एक्सेस प्राप्त करने का प्रयास करते हैं। उस अनुभाग तक प्रतीक्षा करें जब तक कि पहला धागा उस अनुभाग से बाहर नहीं निकल गया। " Ref: सिम्बियन डेवलपर लाइब्रेरी
(एक म्यूटेक्स वास्तव में मूल्य 1 के साथ एक सेमाफोर है)
सेमाफोर:
मुफ्त समान टॉयलेट कीज़ की संख्या है। उदाहरण, मान लें कि हमारे पास समान ताले और कुंजियों के साथ चार शौचालय हैं। सेमाफोर की गिनती - चाबियों की गिनती - शुरुआत में 4 पर सेट होती है (सभी चार शौचालय मुक्त होते हैं), फिर गिनती मूल्य में कमी आती है क्योंकि लोग अंदर आ रहे हैं। यदि सभी शौचालय पूर्ण हैं, अर्थात। कोई मुफ्त कुंजियाँ नहीं बची हैं, सेमाफोर की गिनती 0. अब, जब eq है। एक व्यक्ति शौचालय से बाहर निकलता है, सेमाफोर को 1 (एक मुफ्त कुंजी) तक बढ़ाया जाता है, और कतार में अगले व्यक्ति को दिया जाता है।
आधिकारिक तौर पर: "एक सेमाफोर एक साझा संसाधन के एक साथ उपयोगकर्ताओं की संख्या को अधिकतम संख्या तक सीमित करता है। थ्रेड्स संसाधन (सेमीफ़ायर को घटाते हुए) तक पहुंच का अनुरोध कर सकते हैं, और संकेत दे सकते हैं कि उन्होंने संसाधन का उपयोग करके समाप्त कर दिया है (सेमीफ़ोर को बढ़ाते हुए)। " Ref: सिम्बियन डेवलपर लाइब्रेरी
विषय पर अच्छे लेख:
भाग 2 से:
म्यूटेक्स एक महत्वपूर्ण अंतर के साथ बाइनरी सेमाफोर के सिद्धांतों के समान है: स्वामित्व का सिद्धांत। स्वामित्व सरल अवधारणा है कि जब कोई कार्य किसी म्यूटेक्स को लॉक करता है (प्राप्त करता है) तो वह इसे अनलॉक (रिलीज़) कर सकता है। यदि कोई कार्य किसी म्यूटेक्स को अनलॉक करने का प्रयास करता है, तो उसने लॉक नहीं किया है (इस प्रकार स्वयं का नहीं है) तो एक त्रुटि स्थिति का सामना करना पड़ता है और, सबसे महत्वपूर्ण बात, म्यूटेक्स अनलॉक नहीं है। यदि आपसी अपवर्जन ऑब्जेक्ट का स्वामित्व नहीं है, तो इसे अप्रासंगिक कहा जाता है, यह एक म्यूटेक्स नहीं है।
चूंकि उपरोक्त उत्तर में से कोई भी भ्रम को साफ नहीं करता है, यहाँ एक है जिसने मेरे भ्रम को साफ किया है।
सख्ती से बोलना, एक म्यूटेक्स एक लॉकिंग तंत्र है जिसका उपयोग किसी संसाधन तक पहुंच को सिंक्रनाइज़ करने के लिए किया जाता है। केवल एक ही कार्य (ओएस एब्स्ट्रैक्शन पर आधारित एक धागा या प्रक्रिया हो सकती है) म्यूटेक्स का अधिग्रहण कर सकता है। इसका मतलब है कि म्यूटेक्स से संबंधित स्वामित्व होगा, और केवल मालिक लॉक (म्यूटेक्स) को जारी कर सकता है।
सेमाफोर सिग्नलिंग मैकेनिज्म है ("मैं कर चुका हूं, आप" सिग्नल की तरह ले जा सकते हैं)। उदाहरण के लिए, यदि आप अपने मोबाइल पर गाने सुन रहे हैं (इसे एक कार्य के रूप में मान लें) और उसी समय आपके मित्र ने आपको फोन किया, तो एक व्यवधान उत्पन्न होगा, जिस पर एक रुकावट सेवा दिनचर्या (ISR) कॉल प्रोसेसिंग कार्य को जगाने के लिए संकेत देगी ।
उनके तुल्यकालन शब्दार्थ बहुत अलग हैं:
जैसे कि एक म्यूटेक्स को टास्क से टास्क के लिए पास किया गया और ट्रैफिक रेड-लाइट के रूप में एक सेमाफोर के रूप में देखा जा सकता है (यह किसी को संकेत देता है कि यह आगे बढ़ सकता है)।
सैद्धांतिक स्तर पर, वे शब्दार्थ से भिन्न नहीं हैं। आप सेमीफोर या इसके विपरीत का उपयोग करके म्यूटेक्स लागू कर सकते हैं ( उदाहरण के लिए यहां देखें )। व्यवहार में, कार्यान्वयन अलग है और वे थोड़ी अलग सेवाएं प्रदान करते हैं।
व्यावहारिक अंतर (उनके आसपास के सिस्टम सेवाओं के संदर्भ में) यह है कि एक म्यूटेक्स के कार्यान्वयन का उद्देश्य अधिक हल्के तुल्यकालन तंत्र है। ओरेकल बात में, mutexes रूप में जाना जाता लैच और सेमाफोर रूप में जाना जाता प्रतीक्षा करता है ।
न्यूनतम स्तर पर, वे किसी प्रकार के परमाणु परीक्षण और सेट तंत्र का उपयोग करते हैं। यह एक मेमोरी लोकेशन के वर्तमान मूल्य को पढ़ता है, कुछ प्रकार की सशर्त गणना करता है और एक सिंगल इंस्ट्रक्शन में उस स्थान पर एक मान लिखता है जिसे बाधित नहीं किया जा सकता है । इसका मतलब यह है कि आप म्यूटेक्स का अधिग्रहण कर सकते हैं और यह देखने के लिए परीक्षण कर सकते हैं कि आपके सामने कोई और था या नहीं।
एक सामान्य म्यूटेक्स कार्यान्वयन में एक प्रक्रिया या थ्रेड होता है जो परीक्षण-और-सेट निर्देश को निष्पादित करता है और मूल्यांकन करता है कि क्या म्यूटेक्स ने कुछ और सेट किया था। यहां एक महत्वपूर्ण बिंदु यह है कि अनुसूचक के साथ कोई बातचीत नहीं होती है , इसलिए हमारे पास कोई विचार नहीं है (और परवाह नहीं) जिसने ताला लगा दिया है। फिर हम या तो अपना समय टुकड़ा छोड़ देते हैं और फिर से प्रयास करते हैं जब कार्य फिर से निर्धारित होता है या स्पिन-लॉक निष्पादित करता है । स्पिन लॉक एक एल्गोरिथ्म है जैसे:
Count down from 5000:
i. Execute the test-and-set instruction
ii. If the mutex is clear, we have acquired it in the previous instruction
so we can exit the loop
iii. When we get to zero, give up our time slice.
जब हमने अपना संरक्षित कोड निष्पादित करना समाप्त कर लिया है (एक महत्वपूर्ण अनुभाग के रूप में जाना जाता है ) तो हम म्यूटेक्स मान को शून्य या जो भी मतलब है, उसे सेट करते हैं। ' यदि कई कार्य म्यूटेक्स को प्राप्त करने का प्रयास कर रहे हैं, तो म्यूटेक्स जारी होने के बाद होने वाले अगले कार्य को संसाधन तक पहुंच मिलेगी। आमतौर पर आप एक सिंक्रनाइज़ किए गए संसाधन को नियंत्रित करने के लिए म्यूटेक्स का उपयोग करते हैं जहां विशेष रूप से केवल बहुत कम समय के लिए आवश्यक है, आम तौर पर एक साझा डेटा संरचना को अपडेट करने के लिए।
एक सेमाफोर एक सिंक्रनाइज़ डेटा संरचना है (आमतौर पर एक म्यूटेक्स का उपयोग करके) जिसमें एक गिनती होती है और कुछ सिस्टम कॉल रैपर होते हैं, जो म्यूटेक्स पुस्तकालयों की तुलना में शेड्यूलर के साथ थोड़ी अधिक गहराई में बातचीत करते हैं। सेमाफोर बढ़े और घटे हुए हैं और कुछ और तैयार होने तक कार्यों को अवरुद्ध करने के लिए उपयोग किया जाता है। इसके सरल उदाहरण के लिए निर्माता / उपभोक्ता समस्या देखें । सेमाफोर को कुछ मूल्य के लिए आरम्भ किया जाता है - एक बाइनरी सेमाफोर सिर्फ एक विशेष मामला है जहां सेमाफोर को 1 से शुरू किया जाता है। एक सेमाफोर में पोस्ट करने से एक प्रतीक्षा प्रक्रिया जागने का प्रभाव पड़ता है।
एक बुनियादी सेमाफोर एल्गोरिथ्म जैसा दिखता है:
(somewhere in the program startup)
Initialise the semaphore to its start-up value.
Acquiring a semaphore
i. (synchronised) Attempt to decrement the semaphore value
ii. If the value would be less than zero, put the task on the tail of the list of tasks waiting on the semaphore and give up the time slice.
Posting a semaphore
i. (synchronised) Increment the semaphore value
ii. If the value is greater or equal to the amount requested in the post at the front of the queue, take that task off the queue and make it runnable.
iii. Repeat (ii) for all tasks until the posted value is exhausted or there are no more tasks waiting.
बाइनरी सेमाफोर के मामले में दोनों के बीच मुख्य व्यावहारिक अंतर वास्तविक डेटा संरचना के आसपास के सिस्टम सेवाओं की प्रकृति है।
EDIT: जैसा कि स्पष्ट रूप से बताया गया है, स्पिनकॉक एक प्रोसेसर मशीन को धीमा कर देगा। आप केवल मल्टी-प्रोसेसर बॉक्स पर एक स्पिनलॉक का उपयोग करेंगे क्योंकि किसी एकल प्रोसेसर पर म्यूटेक्स को धारण करने वाली प्रक्रिया कभी भी इसे रीसेट नहीं करेगी जबकि दूसरा कार्य चल रहा है। स्पिनकॉक केवल बहु-प्रोसेसर आर्किटेक्चर पर उपयोगी हैं।
futex
सिस्टम कॉल निम्न-विलंबता उपयोगकर्ता स्थान / सेमीफ़ायर कार्यान्वयन की सहायता के लिए मौजूद है। en.wikipedia.org/wiki/Futex ) नो-कंटेस्टेंट फास्ट पथ में, या यदि संसाधन जल्द ही उपलब्ध हो जाता है, तो आपके पास कभी भी ओवरहेड नहीं होता है एक सिस्टम कॉल लेकिन आप कुछ माइक्रो-सेकंड व्यस्त-प्रतीक्षा (कताई) से अधिक खर्च नहीं करते हैं। स्पिन-लूप बैकऑफ और वेट के मापदंडों को ट्यूनिंग करना हार्डवेयर और वर्कलोड-डिपेंडेंट है, लेकिन मानक लाइब्रेरी में आमतौर पर उचित विकल्प होते हैं।
हालांकि म्यूटेक्स और सेमाफोरेस को सिंक्रोनाइज़ेशन प्राइमेटिव के रूप में उपयोग किया जाता है, लेकिन उनके बीच एक बड़ा अंतर है। म्यूटेक्स के मामले में, केवल वह धागा जो म्यूटेक्स को लॉक या अधिग्रहित करता है, उसे अनलॉक कर सकता है। एक सेमाफोर के मामले में, एक सेमाफोर पर इंतजार कर रहे एक धागे को एक अलग धागे से संकेत दिया जा सकता है। कुछ ऑपरेटिंग सिस्टम प्रक्रिया के बीच म्यूटेक्स और सेमाफोर का उपयोग करके समर्थन करता है। आमतौर पर उपयोग साझा मेमोरी में होता है।
म्यूटेक्स: मान लीजिए कि हमारे पास महत्वपूर्ण अनुभाग थ्रेड है T1 इसे एक्सेस करना चाहता है तो यह चरणों से नीचे है। टी 1:
बाइनरी सेमाफोर: यह सिग्नल प्रतीक्षा और सिग्नल पर आधारित काम करता है। प्रतीक्षा (ओं) में "s" मूल्य एक से कम हो जाता है आमतौर पर "s" मूल्य "1" के साथ आरंभ होता है, संकेत (s) एक से "s" मूल्य बढ़ाता है। यदि "s" मान 1 है, तो कोई भी महत्वपूर्ण अनुभाग का उपयोग नहीं कर रहा है, जब मान 0 का अर्थ है कि महत्वपूर्ण अनुभाग उपयोग में है। मान लीजिए कि T2 महत्वपूर्ण खंड का उपयोग कर रहा है, तो यह चरणों से नीचे है। T2:
म्यूटेक्स और बाइनरी सेमाफोर के बीच मुख्य अंतर म्यूटेक्स में है यदि थ्रेड महत्वपूर्ण खंड को लॉक करता है तो उसे महत्वपूर्ण सेक्शन को अनलॉक करना होगा कोई अन्य थ्रेड इसे अनलॉक नहीं कर सकता है, लेकिन बाइनरी सेमाफोर के मामले में यदि एक थ्रेड प्रतीक्षा (एस) फ़ंक्शन का उपयोग करके महत्वपूर्ण खंड को लॉक करता है: मान s "0" बन जाते हैं और कोई भी इसे तब तक एक्सेस नहीं कर सकता जब तक कि "s" 1 नहीं बन जाता लेकिन मान लीजिए कि कुछ अन्य थ्रेड कॉल सिग्नल (s) हैं तो "s" का मान 1 हो जाता है और यह दूसरे फ़ंक्शन को महत्वपूर्ण सेक्शन का उपयोग करने की अनुमति देता है। इसलिए बाइनरी सेमाफोर धागे में स्वामित्व नहीं है।
विंडोज पर, म्यूटेक्स और बाइनरी सेमाफोर के बीच दो अंतर हैं:
एक म्यूटेक्स केवल उस थ्रेड द्वारा जारी किया जा सकता है जिसके पास स्वामित्व है, यानी वह धागा जिसे पहले वेट फ़ंक्शन कहा जाता है, (या इसे बनाते समय स्वामित्व लिया गया)। एक अर्धचंद्र किसी भी धागे से जारी किया जा सकता है।
एक थ्रेड बिना किसी म्यूटेक्स पर बार-बार प्रतीक्षा फ़ंक्शन को कॉल कर सकता है। हालांकि, यदि आप एक बाइनरी सेमाफोर पर दो बार प्रतीक्षा फ़ंक्शन को बीच में सेमाफ़ोर जारी किए बिना कहते हैं, तो थ्रेड ब्लॉक हो जाएगा।
आप स्पष्ट रूप से एक ही समय में किसी अन्य थ्रेड द्वारा एक्सेस किए जा रहे डेटा को एक थ्रेड में लॉक करने के लिए म्यूटेक्स का उपयोग करते हैं। मान लें कि आपने अभी-अभी कॉल किया है lock()
और डेटा एक्सेस करने की प्रक्रिया में है। इसका मतलब यह है कि आप उसी म्यूटेक्स द्वारा लॉक किए गए समान डेटा तक पहुंचने के लिए किसी अन्य थ्रेड (या समान थ्रेड-कोड का एक और उदाहरण) की अपेक्षा नहीं करते हैं। यही है, अगर यह एक ही थ्रेड-कोड एक अलग थ्रेड उदाहरण पर निष्पादित हो रहा है, लॉक को हिट करता है, तो एlock()
वहाँ नियंत्रण प्रवाह को अवरुद्ध करना चाहिए। यह एक थ्रेड पर लागू होता है जो एक अलग थ्रेड-कोड का उपयोग करता है, जो एक ही डेटा को एक्सेस कर रहा है और जो एक ही म्यूटेक्स द्वारा लॉक भी है। इस स्थिति में, आप अभी भी डेटा तक पहुँचने की प्रक्रिया में हैं और आप कह सकते हैं, म्यूटेक्स अनलॉक तक पहुँचने के लिए एक और 15 सेकंड्स (ताकि म्यूटेक्स लॉक में अवरुद्ध होने वाला दूसरा धागा अनब्लॉक हो जाए और नियंत्रण को अनुमति दे सके) डेटा तक पहुंच)। क्या आप किसी भी कीमत पर केवल एक ही म्यूटेक्स को अनलॉक करने की अनुमति देते हैं, और बदले में, म्यूटेक्स लॉक में पहले से ही प्रतीक्षा कर रहे (अवरुद्ध) डेटा को अनब्लॉक और एक्सेस करने की अनुमति देते हैं? आशा है कि आप यहाँ क्या कह रहे हैं? के अनुसार, सार्वभौमिक परिभाषा पर सहमत हुए!
इसलिए, यदि आप म्यूटेक्स के बजाय बाइनरी-सेमाफोर का उपयोग करने के बारे में बहुत विशेष हैं, तो आपको ताले और अनलॉक "स्कूपिंग" में बहुत सावधान रहना चाहिए। मेरा मतलब है कि हर नियंत्रण-प्रवाह जो हर लॉक को हिट करता है, अनलॉक कॉल को हिट करना चाहिए, साथ ही कोई "पहला अनलॉक" नहीं होना चाहिए, बल्कि यह हमेशा "पहला लॉक" होना चाहिए।
म्यूटेक्स का उपयोग "लॉकिंग मैकेनिज्म" के लिए किया जाता है। एक समय में एक प्रक्रिया एक साझा संसाधन का उपयोग कर सकती है
जहाँ तक
"सिग्नलिंग मैकेनिज्म" जैसे "मैं कर रहा हूँ, अब जारी रख सकते हैं" के लिए सेमाफोर का उपयोग किया जाता है
कल्पित कथा:
युगल के लेख में कहा गया है कि "बाइनरी सेमाफोर और म्यूटेक्स समान हैं" या "मूल्य 1 के साथ सेमाफोर म्यूटेक्स है" लेकिन मूल अंतर केवल म्यूटेक्स को उस थ्रेड द्वारा जारी किया जा सकता है जिसे उसने अधिग्रहित किया था, जबकि आप किसी अन्य थ्रेड के लिए सेमीफोर को संकेत कर सकते हैं।
प्रमुख बिंदु:
• एक धागा एक से अधिक लॉक (म्यूटेक्स) प्राप्त कर सकता है।
• एक म्यूटेक्स केवल एक से अधिक बार लॉक किया जा सकता है यदि इसका पुनरावर्ती म्यूटेक्स, यहां म्यूट के लिए लॉक और अनलॉक समान होना चाहिए
• यदि एक थ्रेड जो पहले से म्यूटेक्स को बंद कर दिया था, म्यूटेक्स को फिर से लॉक करने की कोशिश करता है, तो यह उस म्यूटेक्स की प्रतीक्षा सूची में प्रवेश करेगा, जिसके परिणामस्वरूप गतिरोध होता है।
• बाइनरी सेमाफोर और म्यूटेक्स समान हैं लेकिन समान नहीं हैं।
• इससे जुड़े प्रोटेक्शन प्रोटोकॉल के कारण म्यूटेक्स महंगा ऑपरेशन है।
• म्यूटेक्स का मुख्य उद्देश्य संसाधन तक परमाणु पहुंच या ताला प्राप्त करना है
एक म्यूटेक्स एकल साझा संसाधन तक पहुंच को नियंत्रित करता है। यह उस संसाधन को प्राप्त करने और प्राप्त करने के लिए संचालन प्रदान करता है ( जब किया जाता है ) तब इसे जारी करता है।
एक सेमाफोर संसाधनों के साझा पूल तक पहुंच को नियंत्रित करता है। यह प्रतीक्षा करने के लिए () तब तक संचालन प्रदान करता है जब तक कि पूल में उपलब्ध संसाधनों में से कोई एक उपलब्ध नहीं हो जाता है, और सिग्नल () जब इसे पूल में वापस दिया जाता है।
जब किसी सेमाफोर की रक्षा करने वाले संसाधनों की संख्या 1 से अधिक होती है, तो इसे काउंटिंग सेमाफोर कहा जाता है । जब यह एक संसाधन को नियंत्रित करता है, तो इसे बूलियन सेमाफोर कहा जाता है । एक बूलियन सेमाफोर एक म्यूटेक्स के बराबर है।
इस प्रकार एक सेमाफोर म्यूटेक्स की तुलना में उच्च स्तर का अमूर्त है। एक म्यूटेक्स को सेमाफोर का उपयोग करके लागू किया जा सकता है, लेकिन दूसरे तरीके से नहीं।
संशोधित प्रश्न है - A म्यूटेक्स और "लिनक्स" में "बाइनरी" सेमाफोर के बीच अंतर क्या है?
उत्तर: निम्नलिखित अंतर हैं - i) स्कोप - म्यूटेक्स का दायरा एक प्रक्रिया पता स्थान के भीतर है जिसने इसे बनाया है और इसका उपयोग थ्रेड्स के सिंक्रनाइज़ेशन के लिए किया जाता है। जबकि सेमाफोर का उपयोग प्रोसेस स्पेस में किया जा सकता है और इसलिए इसे इंटरप्रोसेस सिंक्रोनाइज़ेशन के लिए इस्तेमाल किया जा सकता है।
ii) म्यूटेक्स सेमाफोर की तुलना में हल्का और तेज है। Futex और भी तेज है।
iii) म्यूटेक्स को एक ही धागे से सफलतापूर्वक कई बार इस शर्त के साथ हासिल किया जा सकता है कि इसे उसी समय जारी करना चाहिए। अन्य धागा जो हासिल करने की कोशिश कर रहा है वह अवरुद्ध हो जाएगा। जबकि सेमाफोर के मामले में अगर एक ही प्रक्रिया इसे फिर से हासिल करने की कोशिश करती है तो यह ब्लॉक हो जाती है क्योंकि इसे केवल एक बार हासिल किया जा सकता है।
बाइनरी सेमाफोर और म्यूटेक्स के बीच का अंतर: OWNERSHIP: सेमाफोर्स को एक गैर वर्तमान मालिक से भी संकेत (पोस्ट) किया जा सकता है। इसका मतलब है कि आप बस किसी अन्य धागे से पोस्ट कर सकते हैं, हालांकि आप मालिक नहीं हैं।
सेमफोर प्रक्रिया में एक सार्वजनिक संपत्ति है, इसे केवल एक गैर मालिक धागे द्वारा पोस्ट किया जा सकता है। कृपया इस अंतर को BOLD अक्षरों में अंकित करें, इसका अर्थ बहुत है।
म्यूटेक्स महत्वपूर्ण क्षेत्र को अवरुद्ध करने पर काम करता है, लेकिन गणना पर सेमफोर काम करता है।
http://www.geeksforgeeks.org/archives/9102 विवरण में चर्चा करता है।
Mutex
एक संसाधन तक पहुंच को सिंक्रनाइज़ करने के लिए लॉकिंग तंत्र का उपयोग किया जाता है।
Semaphore
सिग्नलिंग तंत्र है।
प्रोग्रामर तक इसका उपयोग अगर वह म्यूटेक्स के स्थान पर बाइनरी सेमाफोर का उपयोग करना चाहता है।
इस तथ्य के अलावा कि म्यूटेक्स का एक मालिक है, दोनों वस्तुओं को अलग-अलग उपयोग के लिए अनुकूलित किया जा सकता है। म्यूटेक्स केवल थोड़े समय के लिए आयोजित होने के लिए डिज़ाइन किए गए हैं; इसका उल्लंघन करने से खराब प्रदर्शन और अनुचित शेड्यूलिंग हो सकती है। उदाहरण के लिए, एक चल रहे धागे को म्यूटेक्स प्राप्त करने की अनुमति दी जा सकती है, भले ही उस पर पहले से ही एक और धागा अवरुद्ध हो। सेमाफोर अधिक निष्पक्षता प्रदान कर सकते हैं, या निष्पक्षता को कई शर्त चर का उपयोग करके मजबूर किया जा सकता है।
sem_post()
के लिए SCHED_FIFO
और SCHED_RR
(इन दोनों को डिफ़ॉल्ट नहीं हैं): सर्वोच्च प्राथमिकता धागा, और यदि एक ही प्राथमिकता, धागा है कि सबसे लंबे समय तक इंतजार कर रहे थे के साथ कई हैं। OpenSolaris सामान्य निर्धारण के लिए भी कुछ हद तक इस FIFO नियम का पालन करता है। Glibc और FreeBSD के लिए, एक साधारण म्यूटेक्स को अनलॉक करना (अर्थात प्राथमिकता सुरक्षा या प्राथमिकता विरासत नहीं है) और एक सेमाफोर पोस्ट करना मूल रूप से एक ही है, ऑब्जेक्ट को अनलॉक किया गया और फिर, यदि वेटिंग थ्रेड्स हो सकते हैं, तो कर्नेल को जगाने के लिए कॉल करना।
जबकि एक बाइनरी सेमाफोर का उपयोग म्यूटेक्स के रूप में किया जा सकता है, एक म्यूटेक्स एक अधिक विशिष्ट उपयोग-केस है, इसमें केवल म्यूटेक्स को लॉक करने वाली प्रक्रिया इसे अनलॉक करने वाली है। यह स्वामित्व बाधा से सुरक्षा प्रदान करना संभव बनाता है:
ये बाधाएं हमेशा मौजूद नहीं होती हैं क्योंकि वे गति को कम करती हैं। अपने कोड के विकास के दौरान, आप इन जांचों को अस्थायी रूप से सक्षम कर सकते हैं।
उदाहरण के लिए आप अपने म्यूटेक्स में त्रुटि जांच विशेषता को सक्षम कर सकते हैं। EDEADLK
यदि आप एक ही दो बार लॉक करने का प्रयास करते हैं और EPERM
यदि आप ऐसा म्यूटेक्स अनलॉक नहीं करते हैं, तो म्यूटेक्स की वापसी की जाँच करने में त्रुटि ।
pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);
एक बार शुरू होने के बाद हम इन चेकों को अपने कोड में इस तरह रख सकते हैं:
if(pthread_mutex_unlock(&mutex)==EPERM)
printf("Unlock failed:Mutex not owned by this thread\n");
उपरोक्त पदों पर जाने के बाद मेरे लिए अवधारणा स्पष्ट थी। लेकिन कुछ अशिष्ट प्रश्न थे। तो, मैंने इस छोटे से कोड को लिखा।
जब हम इसे लेने के बिना एक सेमाफोर देने की कोशिश करते हैं, तो यह हो जाता है। लेकिन, जब आप इसे लेने के बिना म्यूटेक्स देने की कोशिश करते हैं, तो यह विफल हो जाता है। मैंने एक विंडोज प्लेटफॉर्म पर इसका परीक्षण किया। MUTEX का उपयोग करके समान कोड चलाने के लिए USE_MUTEX सक्षम करें।
#include <stdio.h>
#include <windows.h>
#define xUSE_MUTEX 1
#define MAX_SEM_COUNT 1
DWORD WINAPI Thread_no_1( LPVOID lpParam );
DWORD WINAPI Thread_no_2( LPVOID lpParam );
HANDLE Handle_Of_Thread_1 = 0;
HANDLE Handle_Of_Thread_2 = 0;
int Data_Of_Thread_1 = 1;
int Data_Of_Thread_2 = 2;
HANDLE ghMutex = NULL;
HANDLE ghSemaphore = NULL;
int main(void)
{
#ifdef USE_MUTEX
ghMutex = CreateMutex( NULL, FALSE, NULL);
if (ghMutex == NULL)
{
printf("CreateMutex error: %d\n", GetLastError());
return 1;
}
#else
// Create a semaphore with initial and max counts of MAX_SEM_COUNT
ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);
if (ghSemaphore == NULL)
{
printf("CreateSemaphore error: %d\n", GetLastError());
return 1;
}
#endif
// Create thread 1.
Handle_Of_Thread_1 = CreateThread( NULL, 0,Thread_no_1, &Data_Of_Thread_1, 0, NULL);
if ( Handle_Of_Thread_1 == NULL)
{
printf("Create first thread problem \n");
return 1;
}
/* sleep for 5 seconds **/
Sleep(5 * 1000);
/*Create thread 2 */
Handle_Of_Thread_2 = CreateThread( NULL, 0,Thread_no_2, &Data_Of_Thread_2, 0, NULL);
if ( Handle_Of_Thread_2 == NULL)
{
printf("Create second thread problem \n");
return 1;
}
// Sleep for 20 seconds
Sleep(20 * 1000);
printf("Out of the program \n");
return 0;
}
int my_critical_section_code(HANDLE thread_handle)
{
#ifdef USE_MUTEX
if(thread_handle == Handle_Of_Thread_1)
{
/* get the lock */
WaitForSingleObject(ghMutex, INFINITE);
printf("Thread 1 holding the mutex \n");
}
#else
/* get the semaphore */
if(thread_handle == Handle_Of_Thread_1)
{
WaitForSingleObject(ghSemaphore, INFINITE);
printf("Thread 1 holding semaphore \n");
}
#endif
if(thread_handle == Handle_Of_Thread_1)
{
/* sleep for 10 seconds */
Sleep(10 * 1000);
#ifdef USE_MUTEX
printf("Thread 1 about to release mutex \n");
#else
printf("Thread 1 about to release semaphore \n");
#endif
}
else
{
/* sleep for 3 secconds */
Sleep(3 * 1000);
}
#ifdef USE_MUTEX
/* release the lock*/
if(!ReleaseMutex(ghMutex))
{
printf("Release Mutex error in thread %d: error # %d\n", (thread_handle == Handle_Of_Thread_1 ? 1:2),GetLastError());
}
#else
if (!ReleaseSemaphore(ghSemaphore,1,NULL) )
{
printf("ReleaseSemaphore error in thread %d: error # %d\n",(thread_handle == Handle_Of_Thread_1 ? 1:2), GetLastError());
}
#endif
return 0;
}
DWORD WINAPI Thread_no_1( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_1);
return 0;
}
DWORD WINAPI Thread_no_2( LPVOID lpParam )
{
my_critical_section_code(Handle_Of_Thread_2);
return 0;
}
बहुत तथ्य यह है कि सेमाफोर आपको सिग्नल देता है "यह एक संसाधन का उपयोग करके किया जाता है", भले ही यह संसाधन के स्वामित्व में न हो, मुझे लगता है कि सेमीफोर के मामले में मालिक और सिग्नलिंग के बीच बहुत ढीली युग्मन है।
संवेदनशील कोड और डेटा की सुरक्षा के लिए म्यूटेक्स का उपयोग किया जाता है, सेमाफोर को सिंक्रोनाइज़ेशन के लिए उपयोग किया जाता है। आप संवेदनशील कोड की सुरक्षा के साथ व्यावहारिक उपयोग भी कर सकते हैं, लेकिन एक जोखिम हो सकता है जो ऑपरेशन V.So द्वारा अन्य थ्रेड द्वारा सुरक्षा को जारी करता है। द्वि-सेमाफोर और म्यूटेक्स के बीच का अंतर स्वामित्व है। शौचालय द्वारा उदाहरण के लिए, म्यूटेक्स ऐसा है कि कोई शौचालय में प्रवेश कर सकता है और दरवाजा बंद कर सकता है, कोई और तब तक प्रवेश नहीं कर सकता जब तक कि आदमी बाहर नहीं निकलता, द्वि-अर्ध-प्रवेश ऐसा है कि कोई भी प्रवेश कर सकता है शौचालय और दरवाजा बंद है, लेकिन कोई और व्यक्ति व्यवस्थापक से दरवाजा खोलने के लिए कहकर प्रवेश कर सकता है, यह हास्यास्पद है।
म्युटेक्स
Mutexes का उपयोग आमतौर पर री-एंट्रेंट कोड के एक सेक्शन तक पहुंच को क्रमबद्ध करने के लिए किया जाता है जिसे एक से अधिक थ्रेड द्वारा समवर्ती रूप से निष्पादित नहीं किया जा सकता है। एक म्यूटेक्स ऑब्जेक्ट केवल एक थ्रेड को नियंत्रित अनुभाग में अनुमति देता है, अन्य थ्रेड्स को मजबूर करता है जो उस सेक्शन तक पहुंच प्राप्त करने का प्रयास करता है जब तक कि पहला थ्रेड उस खंड से बाहर नहीं निकलता है। एक म्यूटेक्स का उपयोग किसी साझा संसाधन की सुरक्षा के लिए खतरनाक हो सकता है। अनपेक्षित दुष्प्रभाव। किसी भी दो RTOS कार्य जो विभिन्न प्राथमिकताओं पर काम करते हैं और एक म्यूटेक्स के माध्यम से समन्वय करते हैं, प्राथमिकता उलटा के लिए अवसर बनाते हैं । Mutex यूजर स्पेस में काम करता है ।
सिकंदरा
सेमाफोर एक सिग्नलिंग तंत्र है। सेमीफ़ोर एक साझा संसाधन के एक साथ उपयोगकर्ताओं की संख्या को अधिकतम संख्या तक सीमित करता है। थ्रेड्स संसाधन तक पहुँच प्राप्त कर सकते हैं (सेमाफोर को घटाकर) और यह संकेत दे सकते हैं कि उन्होंने संसाधन का उपयोग कर (सेमाफोर को बढ़ाकर) समाप्त कर दिया है। यह साझा संसाधनों तक पहुंचने के लिए थ्रेड की संख्या की अनुमति देता है। एक सेमाफोर का सही उपयोग एक कार्य से दूसरे में सिग्नलिंग के लिए होता है। सिमफोर का उपयोग एक बाधा सेवा दिनचर्या से संकेत देने के लिए भी किया जा सकता है। (ISR) । एक सेमाफोर सिग्नलिंग एक गैर-अवरुद्ध आरटीओएस व्यवहार है और इस प्रकार आईएसआर सुरक्षित है। क्योंकि यह तकनीक कार्य स्तर पर व्यवधान को अक्षम करने के लिए त्रुटि-प्रवण को समाप्त करती है। यह कर्नेल स्थान में काम करता है ।
जवाब लक्ष्य ओएस पर निर्भर हो सकता है। उदाहरण के लिए, कम से कम एक आरटीओएस कार्यान्वयन से मैं परिचित हूं जो कई अनुक्रमिक "एकल ओएस म्यूटेक्स के खिलाफ" ऑपरेशन करने की अनुमति देगा, इसलिए जब तक वे सभी एक ही थ्रेड संदर्भ में नहीं होते। एक और धागा को म्यूटेक्स प्राप्त करने की अनुमति देने से पहले कई हो जाता है एक समान संख्या में पुट द्वारा प्रतिस्थापित किया जाना चाहिए। यह बाइनरी सेमाफोर्स से भिन्न होता है, जिसके लिए थ्रेड संदर्भों की परवाह किए बिना, केवल एक ही बार अनुमति मिलती है।
इस प्रकार के म्यूटेक्स के पीछे विचार यह है कि आप किसी ऑब्जेक्ट को एक बार में डेटा को संशोधित करने की अनुमति देकर किसी ऑब्जेक्ट की सुरक्षा करते हैं। यहां तक कि अगर थ्रेड को म्यूटेक्स मिलता है और फिर एक फ़ंक्शन को कॉल करता है जो ऑब्जेक्ट को और संशोधित करता है (और अपने स्वयं के संचालन के चारों ओर रक्षक म्यूटेक्स डालता है), ऑपरेशन अभी भी सुरक्षित होना चाहिए क्योंकि वे सभी एक ही थ्रेड के तहत हो रहे हैं।
{
mutexGet(); // Other threads can no longer get the mutex.
// Make changes to the protected object.
// ...
objectModify(); // Also gets/puts the mutex. Only allowed from this thread context.
// Make more changes to the protected object.
// ...
mutexPut(); // Finally allows other threads to get the mutex.
}
बेशक, इस सुविधा का उपयोग करते समय, आपको निश्चित होना चाहिए कि एक ही धागे के भीतर सभी पहुंच वास्तव में सुरक्षित हैं!
मुझे यकीन नहीं है कि यह दृष्टिकोण कितना सामान्य है, या क्या यह उन प्रणालियों के बाहर लागू होता है जिनके साथ मैं परिचित हूं। इस तरह के म्यूटेक्स के उदाहरण के लिए, थ्रेडएक्स आरटीओएस देखें।
म्यूटेक्स का स्वामित्व है, सेमाफोरस के विपरीत। यद्यपि कोई भी धागा, म्यूटेक्स के दायरे में, एक अनलॉक किए गए म्यूटेक्स को प्राप्त कर सकता है और कोड के समान महत्वपूर्ण अनुभाग तक लॉक एक्सेस कर सकता है, केवल एक म्यूटेक्स को लॉक करने वाले धागे को इसे अनलॉक करना चाहिए ।
जैसा कि यहां कई लोगों ने उल्लेख किया है, एक म्यूटेक्स कोड (AKA महत्वपूर्ण अनुभाग) के एक महत्वपूर्ण टुकड़े की सुरक्षा के लिए उपयोग किया जाता है। आप म्यूटेक्स (लॉक) का अधिग्रहण करेंगे, महत्वपूर्ण अनुभाग दर्ज करेंगे, और सभी mutex (अनलॉक) को एक ही धागे में जारी करेंगे। ।
एक सेमाफोर का उपयोग करते समय, आप एक धागा को सेमीफोर (थ्रेड ए) पर प्रतीक्षा कर सकते हैं, जब तक कि एक और धागा (थ्रेड बी) जो भी कार्य पूरा करता है, और फिर प्रतीक्षा को रोकने के लिए थ्रेड ए के लिए सेमाफोर सेट करता है, और अपना कार्य जारी रखता है।
सबसे अच्छा उपाय
फर्क सिर्फ इतना है
1. म्यूटेक्स -> लॉक और अनलॉक एक थ्रेड के स्वामित्व में हैं जो म्यूटेक्स को लॉक करता है।
2. सेमाफोर -> कोई स्वामित्व नहीं; यदि एक थ्रेड सेमीवेट (एस) को कॉल करता है, तो लॉक को हटाने के लिए कोई भी थ्रेड सेमीपोस्ट (एस) को कॉल कर सकता है।
म्युटेक्स
कुछ समय पहले तक, कर्नेल में एकमात्र स्लीपिंग लॉक सेमीफोर था। सेमाफोर के अधिकांश उपयोगकर्ताओं ने एक की गणना के साथ एक सेमाफोर को तुरंत हटा दिया और उन्हें एक बाहरी बहिष्करण लॉक के रूप में माना- एक स्लीप ऑफ वर्जन ऑफ स्पिन-लॉक। दुर्भाग्य से, सेमाफोर बल्कि सामान्य हैं और किसी भी उपयोग की बाधा नहीं डालते हैं। यह उन्हें अस्पष्ट स्थितियों में विशेष पहुंच के प्रबंधन के लिए उपयोगी बनाता है, जैसे कर्नेल और उपयोगकर्ता के बीच जटिल नृत्य। लेकिन इसका मतलब यह भी है कि सरल लॉकिंग करना कठिन है, और लागू नियमों की कमी किसी भी प्रकार की स्वचालित डिबगिंग या बाधा प्रवर्तन को असंभव बना देती है। एक सरल स्लीपिंग लॉक की तलाश में, कर्नेल डेवलपर्स ने म्यूटेक्स को पेश किया। हाँ, जैसा कि आप अब आदी हैं, यह एक भ्रमित नाम है। आइए स्पष्ट करते हैं। "म्यूटेक्स" शब्द किसी भी स्लीपिंग लॉक को संदर्भित करने के लिए एक सामान्य नाम है जो पारस्परिक बहिष्करण को लागू करता है, एक के उपयोग की गणना के साथ एक सेमाफोर जैसे। हाल के लिनक्स कर्नेल में, उचित संज्ञा "म्यूटेक्स" अब एक विशिष्ट प्रकार का स्लीपिंग लॉक है जो आपसी बहिष्करण को लागू करता है। यह एक म्यूटेक्स एक म्यूटेक्स है।
म्यूटेक्स की सादगी और दक्षता अतिरिक्त उपयोगकर्ताओं द्वारा अपने उपयोक्ताओं पर लगाए गए अतिरिक्त अवरोधों से आती है, जो कि अर्धचालक की आवश्यकता होती है। एक सेमाफोर के विपरीत, जो दिज्क्स्ट्रा के मूल डिजाइन के अनुसार व्यवहार के सबसे बुनियादी को लागू करता है, म्यूटेक्स में एक सख्त, संकीर्ण उपयोग मामला है: एक समय में केवल एक कार्य म्यूटेक्स को पकड़ सकता है। यही है, म्यूटेक्स पर उपयोग गणना हमेशा एक होती है।
[१] लिनक्स कर्नेल विकास, तीसरा संस्करण रॉबर्ट लव
मुझे लगता है कि यहां अधिकांश उत्तर विशेष रूप से भ्रमित करने वाले थे, यह कहते हुए कि म्यूटेक्स को केवल उस प्रक्रिया द्वारा जारी किया जा सकता है जो इसे रखती है, लेकिन अर्ध प्रक्रिया को ay प्रक्रिया द्वारा संकेत दिया जा सकता है। उपर्युक्त रेखा सेमाफोर के संदर्भ में अस्पष्ट है। समझने के लिए हमें पता होना चाहिए कि दो प्रकार के सेमाफोर होते हैं एक को सेमाफोर कहा जाता है और दूसरे को बाइनरी सेमाफोर कहा जाता है। गिनती में सेमाफोर उन संसाधनों की संख्या तक पहुंच को संभालता है जहां उपयोग से पहले एन को परिभाषित किया जा सकता है। प्रत्येक सेमाफोर में एक गणना चर होता है, जो उपयोग में संसाधनों की संख्या की गिनती रखता है, शुरू में, यह n पर सेट होता है। प्रत्येक प्रक्रिया जो किसी संसाधन का उपयोग करना चाहती है, वह सेमाफोर पर एक प्रतीक्षा () ऑपरेशन करती है (जिससे गिनती में कमी होती है)। जब कोई प्रक्रिया एक संसाधन जारी करती है, तो यह एक रिलीज () ऑपरेशन (गिनती में वृद्धि) करती है। जब गिनती 0 हो जाती है, सभी संसाधनों का उपयोग किया जा रहा है। उसके बाद, प्रक्रिया प्रतीक्षा करती है जब तक कि गिनती 0. से अधिक नहीं हो जाती है। अब यहां केवल उस प्रक्रिया को पकड़ना है जो संसाधन रखता है गिनती बढ़ा सकता है कोई अन्य प्रक्रिया गिनती को बढ़ा सकती है केवल संसाधन रखने वाली प्रक्रिया गिनती और प्रक्रिया को बढ़ा सकती है। सेमाफोर की प्रतीक्षा फिर से जाँच करता है और जब यह उपलब्ध संसाधन को देखता है तो यह फिर से गिनती को कम कर देता है। तो बाइनरी सेमाफोर के संदर्भ में, केवल सेमाफोर धारण करने की प्रक्रिया गिनती को बढ़ा सकती है, और गिनती तब तक शून्य रहती है जब तक कि यह सेमीफोर का उपयोग करना बंद नहीं करता है और गिनती बढ़ जाती है और अन्य प्रक्रिया को सेमीफोर तक पहुंचने का मौका मिलता है। अब यहाँ केवल उस प्रक्रिया को पकड़ा जा सकता है जो संसाधन रखती है, गिनती बढ़ा सकती है कोई अन्य प्रक्रिया नहीं बढ़ा सकती है केवल एक संसाधन रखने वाली प्रक्रिया गिनती को बढ़ा सकती है और अर्धवृत्त की प्रतीक्षा करने वाली प्रक्रिया फिर से जाँच करती है और जब यह संसाधन उपलब्ध देखता है गिनती फिर से घट जाती है। तो बाइनरी सेमाफोर के संदर्भ में, केवल सेमाफोर धारण करने की प्रक्रिया गिनती को बढ़ा सकती है, और गिनती तब तक शून्य रहती है जब तक कि यह सेमीफोर का उपयोग करना बंद नहीं करता है और गिनती बढ़ जाती है और अन्य प्रक्रिया को सेमीफोर तक पहुंचने का मौका मिलता है। अब यहाँ केवल उस प्रक्रिया को पकड़ा जा सकता है जो संसाधन रखती है, गिनती बढ़ा सकती है कोई अन्य प्रक्रिया नहीं बढ़ा सकती है केवल एक संसाधन रखने वाली प्रक्रिया गिनती को बढ़ा सकती है और अर्धवृत्त की प्रतीक्षा करने वाली प्रक्रिया फिर से जाँच करती है और जब यह संसाधन उपलब्ध देखता है गिनती फिर से घट जाती है। तो बाइनरी सेमाफोर के संदर्भ में, केवल सेमाफोर धारण करने की प्रक्रिया गिनती को बढ़ा सकती है, और गिनती तब तक शून्य रहती है जब तक कि यह सेमीफोर का उपयोग करना बंद नहीं करता है और गिनती बढ़ जाती है और अन्य प्रक्रिया को सेमीफोर तक पहुंचने का मौका मिलता है।
बाइनरी सेमाफोर और म्यूटेक्स के बीच मुख्य अंतर यह है कि सेमाफोर एक सिग्नलिंग तंत्र है और म्यूटेक्स एक लॉकिंग मैकेनिज्म है, लेकिन बाइनरी सेमाफोर म्यूटेक्स की तरह कार्य करता है जो भ्रम पैदा करता है, लेकिन दोनों अलग-अलग तरह के काम के लिए उपयुक्त विभिन्न अवधारणाएं हैं।