2013-06-24 4 views
7

मैं सोच रहा था: ताला लगा एक कोड क्षेत्रऑटोरसेट Event सी # में लॉक प्रतिस्थापन के रूप में?

दर्ज करें और हैंडल प्रतीक्षा करने के लिए केवल 1 धागा अनुमति देता है संकेतन के लिए है:

सिग्नलिंग जब एक धागा प्रतीक्षा करता है जब तक यह दूसरे से सूचना प्राप्त है।

तो मैंने खुद को सोचा, क्या इसका उपयोग लॉक को प्रतिस्थापित करने के लिए किया जा सकता है?

कुछ की तरह:

Thread number 1 --please enter (autoreset --> autlock) 
dowork... 
finish work... 
set signal to invite the next thread 

तो मैं यह लिखा:

/*1*/ static EventWaitHandle _waitHandle = new AutoResetEvent(true); 
/*2*/ 
/*3*/ volatile int i = 0; 
/*4*/ void Main() 
/*5*/ { 
/*6*/ 
/*7*/  for (int k = 0; k < 10; k++) 
/*8*/  { 
/*9*/   var g = i; 
/*10*/   Interlocked.Increment(ref i); 
/*11*/   new Thread(() = > DoWork(g)).Start(); 
/*12*/ 
/*13*/  } 
/*14*/ 
/*15*/  Console.ReadLine(); 
/*16*/ } 
/*17*/ 
/*18*/ 
/*19*/ void DoWork(object o) 
/*20*/ { 
/*21*/  _waitHandle.WaitOne(); 
/*22*/  Thread.Sleep(10); 
/*23*/  Console.WriteLine((int) o + "Working..."); 
/*24*/  _waitHandle.Set(); 
/*25*/ 
/*26*/ } 

जैसा कि आप देख सकते हैं: लाइनों # 21, # 24 लॉक के लिए प्रतिस्थापन कर रहे हैं।

प्रश्न:

  • यह एक वैध प्रतिस्थापन है? (नहीं कि मैं lock को प्रतिस्थापित करूंगा, लेकिन उपयोग परिदृश्यों के बारे में जानना चाहता हूं)
  • मुझे प्रत्येक का उपयोग कब करना चाहिए?

धन्यवाद।

अजीब लेकिन इतना _lock vs EventWaitHandle_

+0

एसओ के समान प्रश्न हैं: http://stackoverflow.com/questions/1717194/autoresetevent-manualresetevent-vs-monitor – empi

+0

@empi हे, सभी 3 शब्द सामान्य संरचना में हैं (monitor.enter बनाम लॉक, ऑटोरेसेट बनाम waithandle ....) लेकिन हाँ यह समान है।हालांकि कृपया ध्यान दें कि 'AutoResetEvent/waithdnales' ** ** प्रक्रियाओं के बीच साझा नहीं किए गए हैं **। म्यूटेक्स के साथ उलझन में लेखक। वैसे भी वह गलत है। (उसके बारे में)। –

+0

@empi एक सेट कमांड होने पर मतभेदों के बारे में सबसे अधिक रेटेड उत्तर वार्ता (मौसम अगर प्रतीक्षा कर रहा है या नहीं)। –

उत्तर

11

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

वेटहैंडल्स ऐसी गारंटी प्रदान नहीं करते हैं। लॉक का विरोध होने पर बहुत हानिकारक है, वही थ्रेड इसे बार-बार प्राप्त कर सकता है और अन्य धागे हमेशा के लिए भूखे हो सकते हैं।

ताले के लिए उपयुक्त सिंक्रनाइज़ेशन ऑब्जेक्ट का उपयोग करें। प्रतीक्षा करें हैंडल केवल सिग्नलिंग के लिए इस्तेमाल किया जाना चाहिए।

+0

_fairness_ - क्या इसका मतलब है कि अगर धागे: 1,5,7 (उस क्रम में) लॉक क्षेत्र में आए, तो लॉक (जब जारी किया जाएगा) उचित होगा और यह थ्रेड 1 -> 5 -> 7? (जबकि प्रतीक्षा हैंडल कर सकते हैं: 1 -> 1 -> 1 - क्योंकि धागे में उच्च प्रक्रिया/थ्रेड प्राथमिकता हो सकती है?) –

+0

एपीसी से संबंधित कुछ प्रश्नोत्तरी हैं इसलिए यह कड़ाई से मामला नहीं है। लेकिन हां, यह सामान्य क्रम है जिसमें थ्रेड लॉक प्राप्त करते हैं जब सिंक ऑब्जेक्ट निष्पक्षता का वादा करता है। –

+0

हंस मैं कहीं भी पढ़ता हूं कि: यदि ** कोई अन्य धागा ** नहीं है जो लॉक चाहते हैं - कर्नेल संसाधन (या ऐसा कुछ) भी नहीं लिया गया है .... क्या आप मुझे सही शब्द के लिए संदर्भित कर सकते हैं? –

1

यह संभव है के बारे में एक सवाल शामिल नहीं है, लेकिन यह ताला() और बहुत कठिन बनाए रखने के लिए की तुलना में काफी धीमी है।

वैसे, आपको इसे बनाए रखने के लिए इंटरलाक्ड-विधियों का उपयोग करते समय सीधे एक मूल्य नहीं पढ़ना चाहिए।

आपका कोड इस तरह दिखना चाहिए:

var g = Interlocked.Increment(ref i); 

तो जी एक abitrary पिछले मान के बजाय बढ़ती मूल्य शामिल होंगे।

संबंधित मुद्दे