2011-04-08 12 views
10

कोई सैमफोर का उपयोग कब करेगा?मुझे सेफफोर्स का उपयोग कब करना चाहिए?

केवल उदाहरण मैं के धागे एक ही डेटा/कोड एक साथ तक पहुँचने की संख्या सीमित है सोच सकते हैं ...

किसी भी अन्य स्थितियों में जो सेमाफोर सबसे अच्छा समाधान हो सकता है?

+2

संबंधित: http://stackoverflow.com/questions/2350544/in-what- स्थिति-do-you-use-a-semaphore-over-a-mutex-in-c –

+0

एक उदाहरण: http: // स्टैक ओवरफ़्लो।कॉम/प्रश्न/2375132/रिलीजमेफोर-डू-रिलीज-द-सेमफोर/2375370 # 2375370 –

उत्तर

5

सेमफोर प्रक्रियाओं के बीच संकेत के लिए उपयुक्त हो सकता है। बहुप्रचारित प्रोग्रामिंग के लिए, सेमफोर से बचा जाना चाहिए। यदि आपको किसी संसाधन के लिए विशेष पहुंच की आवश्यकता है, तो mutex का उपयोग करें। यदि आपको सिग्नल की प्रतीक्षा करने की आवश्यकता है, तो कंडीशन वैरिएबल का उपयोग करें।

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

wait for semaphore to open 
take a resource out of the pool 
use the resource 
put it back to the pool 
open the semaphore for one more thread 

पहले समस्या यह है कि सेमाफोर कई धागे द्वारा पहुँचा जा रहा से पूल की रक्षा नहीं करता है। तो, एक और सुरक्षा की आवश्यकता है। यह एक ताला होने दो:

wait for semaphore to open 
acquire the lock for the pool 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
open the semaphore for one more thread 

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

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

स्थिति परिवर्तनीय के साथ, यह आसानी से सुलझाया जाता है।

acquire the lock 
while the resource pool is empty, 
    wait for condition variable to be signaled 
take a resource out of the pool 
release the lock 
use the resource 
acquire the lock 
put the resource back to the pool 
release the lock 
signal the condition variable 

और इस मामले में गैर-अवरुद्ध अधिग्रहण को जोड़ने के लिए कोई समस्या नहीं है:

acquire the lock 
if the resource pool is not empty, 
    take a resource out of the pool 
release the lock 
if the pool was empty, return 

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

3

कनेक्शन पूल।

आईई। आपके पास 20 कनेक्शन और 150 धागे हैं। उस स्थिति में आपके पास 20 कनेक्शन तक पहुंच नियंत्रित करने के लिए एक सेमफोर होगा।

+0

+1: अच्छा सरल उदाहरण है, लेकिन मुझे आश्चर्य है कि क्या कोई अन्य स्थितियां है कि सेफफोर्स के लिए अच्छा होगा ... –

2

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