मैं सेमाफोर और सेमाफोरस्लीम के बीच कैसे चुनूं?


109

उनके सार्वजनिक इंटरफेस समान दिखाई देते हैं। प्रलेखन कहा गया है कि SemaphoreSlim एक हल्के विकल्प है और Windows कर्नेल संकेतबाहु उपयोग नहीं करता। यह संसाधन बताता है कि SemaphoreSlim बहुत तेज है। सेमाफोरसम में किन स्थितियों में सेमीफोर और इसके विपरीत अधिक समझ आती है?


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

जवाबों:


64

एक अंतर यह है कि SemaphoreSlimसेमाफोरस नाम की अनुमति नहीं है, जो सिस्टम-वाइड हो सकती है। इसका मतलब यह होगा कि क्रॉस-प्रोसेस सिंक्रोनाइज़ेशन के लिए एक सेमाफोरस्लीम का उपयोग नहीं किया जा सकता है।

MSDN प्रलेखन यह भी इंगित करता है कि SemSlim का उपयोग तब किया जाना चाहिए जब "प्रतीक्षा समय बहुत कम होने की उम्मीद है"। यह आमतौर पर इस विचार के साथ अच्छा होगा कि स्लिम संस्करण अधिक से अधिक व्यापार के लिए अधिक हल्का है।


66
काश, एमएस ने लिखा होता कि क्या होता है जब प्रतीक्षा समय "बहुत कम" नहीं होता है।
जॉन रेनॉल्ड्स

79
... या "बहुत कम" का अर्थ है
रिचर्ड सजेले

9
सिस्टम पर निर्भर करते हुए, सेमफोर के लिए 1 माइक्रोसेकंड और सेमाफोरस्लीम के लिए 1/4 माइक्रोसेकंड एक वेटऑन या रिलीज करने के लिए ["सी # 5.0 इन नटशेल" पीजी। 890] तो हो सकता है कि वे बहुत कम प्रतीक्षा समय से क्या मतलब रखते हैं?
डेविड शेरेट

2
@dhsto अच्छा संदर्भ! लेकिन मैं यह अनुमान लगा रहा हूं कि लिंक किए गए लेख का अर्थ है "जब साझा संसाधन तक पहुंचने के लिए प्रतीक्षा समय बहुत कम हो" - यानी संसाधन लंबे समय तक अनन्य उपयोग में नहीं रहेंगे - इसके बजाय अर्ध-कोड के लिए प्रतीक्षा समय ही मतलब है? सेमाफ़ोर कोड को हमेशा निष्पादित किया जाएगा, भले ही संसाधन को बंद रखा जाए।
17

4
@culix सेमाफोर बनाम सेमाफोरस्लिम के स्रोत को देखते हुए मुझे मुख्य कारण यह है कि सेमाफोरस्लीम का उपयोग केवल "बहुत ही कम" प्रतीक्षा के लिए किया जाना चाहिए क्योंकि यह स्पिन प्रतीक्षा का उपयोग करता है। यह अधिक उत्तरदायी है, लेकिन बहुत अधिक सीपीयू खाता है और लंबे समय तक प्रतीक्षा के लिए बेकार होगा जहां तात्कालिक प्रतिक्रियाएं कम महत्वपूर्ण हैं। सेमाफोर इसके बजाय धागे को अवरुद्ध करता है।
r2_118

17

MSDN प्रलेखन अंतर का वर्णन करता है।

एक वाक्य में:

  • SemaphoreSlim वर्ग एक हल्के, तेजी से होने वाले सेमाफोर का प्रतिनिधित्व करता है जिसका उपयोग किसी एकल प्रक्रिया के भीतर प्रतीक्षा के लिए किया जा सकता है जब प्रतीक्षा समय बहुत कम होने की उम्मीद की जाती है।

1
इसे जोड़ने के लिए, सभी मामलों में सेमाफोरस्लाइम का उपयोग करें जहां आपका आवेदन आपके कंप्यूटर पर एकमात्र प्रक्रिया है जो उस सेमाफोर तक पहुंचने की आवश्यकता है।
ऑस्टिन सालगाट

2
@Salgat आप ऐसा क्यों करेंगे? जैसा कि अन्य उत्तरों में उल्लिखित है, SemaphoreSlimस्पिनवाइट का उपयोग करके कार्यान्वित किया जाता है, इसलिए यदि आप इस पर बहुत इंतजार करते हैं, तो आप बहुत अधिक सीपीयू समय बर्बाद करेंगे। अगर आपकी प्रक्रिया कंप्यूटर पर एकमात्र प्रक्रिया है, तो यह भी एक अच्छा विचार नहीं है।
M.Stramm

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

17

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

सेमाफोर ओएस कर्नेल में कार्यान्वयन पर निर्भर करता है, इसलिए हर बार जब आप लॉक का अधिग्रहण करते हैं, तो आप काफी सीपीयू चक्र खर्च करते हैं, लेकिन उसके बाद धागा केवल लॉक प्राप्त करने के लिए आवश्यक रूप से लंबे समय तक सोता है।


12

"कम समय" विवाद के बारे में:

कम से कम SemaphoreSlim MSDN प्रलेखन में कहा गया है कि

SemaphoreSlim वर्ग एक एकल अनुप्रयोग के भीतर सिंक्रनाइज़ेशन के लिए अनुशंसित सेमाफोर है।

रिमार्क्स अनुभाग में। एक ही खंड सेमीफोर और सेमफोरस्लीम के बीच मुख्य अंतर भी बताता है:

SemaphoreSlim Semaphore वर्ग का एक हल्का विकल्प है जो Windows कर्नेल सेमाफोर का उपयोग नहीं करता है। सेमाफोर वर्ग के विपरीत, सेमफोरस्लीम क्लास सिस्टम सेमाफोर्स नाम का समर्थन नहीं करता है। आप इसे केवल स्थानीय अर्धवृत्त के रूप में उपयोग कर सकते हैं।


1
अधिक विवरण: [SemaphoreSlim and other locks] use busy spinning for brief periods before they put the thread into a true Wait state. When wait times are expected to be very short, spinning is far less computationally expensive than waiting, which involves an expensive kernel transition: dotnet.github.io/docs/essentials/collections/...
मार्को सुल्ला

0

मैंने यहाँ स्रोत कोड को देखा और यही मैं इसके साथ आया:

  1. दोनों Semaphore और SemaphoreSlim WaitHandle से प्राप्त होते हैं जो आंतरिक रूप से Win32 देशी हैंडल का उपयोग करता है। जिसके कारण आपको दोनों को Dispose () करने की आवश्यकता है। तो यह धारणा कि स्लिम लाइटवेट है संदिग्ध है।

  2. SemaphoreSlim आंतरिक रूप से SpinWait का उपयोग करता है जबकि Semaphore नहीं करता है। यह मुझे बताता है कि जिन मामलों में प्रतीक्षा लंबी होने की उम्मीद है, सेमाफोर को कम से कम इस अर्थ में बेहतर करना चाहिए कि यह आपके सीपीयू को नहीं काटेगा।


2
SemaphoreSlim WaitHandle से प्राप्त नहीं है। वास्तव में यह एक ही लक्ष्य के साथ बनाया गया था - ऐसे कार्यों में, जहां आपको केवल एक प्रक्रिया के अंदर संचालन को सिंक्रनाइज़ करने की आवश्यकता है, वेटहैंडल से व्युत्पन्न को खत्म करने के लिए।
इगोर वी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.