2009-08-25 19 views
6

चलो कहते हैं कि मैं तो मान लें कि निम्नलिखित कोडधागे फीफो पर इंतजार कर रहे धागे हैं?

static class ... 
{ 
    static object myobj = new object(); 

    static void mymethod() 
    { 
     lock(myobj) 
     { 
      // my code.... 
     } 
    } 
} 

करते हैं कि thread1 ताला thread2 MyMethod चलाने की कोशिश करता है, जबकि। क्या यह लॉक को रिलीज़ करने या अपवाद फेंकने की प्रतीक्षा करेगा?

यदि यह प्रतीक्षा करता है, तो आदेश सुनिश्चित किया जाता है कि अगर अतिरिक्त धागे आते हैं तो वे फीफो हैं?

उत्तर

8

मेरा उत्तर अपडेट किया गया: वे कतारबद्ध हैं, लेकिन ऑर्डर फीफो होने की गारंटी नहीं है। इस लिंक बाहर

की जांच: http://www.albahari.com/threading/part2.aspx

+4

जरूरी नहीं, देखें: http://stackoverflow.com/questions/961869/is-there-a-synchronization-class-that-guarantee-fifo-order-in-c/961904 –

-1

यह इंतजार करेंगे, और वे उसी क्रम में नहीं किया जाएगा।

अपनी आवश्यकताओं के आधार पर आप अगर आप की तुलना में एक ReaderWriterLock या कुछ अन्य की तरह कुछ पर देखने के अधिक प्रदर्शन हो सकता है सिर्फ lock

+1

वे समान नहीं हैं आदेश। –

3

यह अपने कोड से स्पष्ट नहीं है कि कैसे करता myobjmymethod अंदर दिखाई दे सकता है मिलता है। ऐसा लगता है कि var myobj घोषणा स्कोप पर एक स्थानीय स्टैक वैरिएबल है (क्योंकि var है)। उस स्थिति में यह हो सकता है कि प्रत्येक थ्रेड के पास इसका एक अलग उदाहरण होगा और mymethod ब्लॉक नहीं होगा।

अद्यतन

बारे में पूरी फीफो तर्क, कुछ पृष्ठभूमि की जानकारी आवश्यक है: CLR समन्वयन प्रदान नहीं करता है। यह सीएलआर होस्ट है जो इसे सेवा सीएलआर रनटाइम में प्रदान करता है। मेजबान IHostSyncManager और अन्य इंटरफेस लागू करता है और विभिन्न सिंक्रनाइज़ेशन प्राइमेटिव प्रदान करता है। यह सबसे आम मेजबान के रूप में अप्रचलित प्रतीत हो सकता है (यानी आप संकलित और exe) और यह ओएस को सभी सिंक्रनाइज़ेशन (Win32 एपीआई में आपके पुराने पेटज़ोल्ड पुस्तक primitives) को हटा देता है। हालांकि कम से कम दो और प्रमुख होस्टिंग evironments हैं: ASP.Net एक (मुझे यकीन नहीं है कि यह क्या करता है) और SQL सर्वर। मैं निश्चित रूप से क्या कह सकता हूं कि SQL सर्वर SOS (जो मूल रूप से एक उपयोगकर्ता अधिक ऑपरेटिंग सिस्टम है) पर सभी प्राइमेटिव प्रदान करता है, कभी भी ओएस प्राइमेटिव को स्पर्श नहीं करता है, और एसओएस प्राइमेटिव लॉक कफॉय से बचने के लिए डिज़ाइन द्वारा अनुचित होते हैं (यानी। guranteed कोई फीफो)। चूंकि अन्य प्रतिक्रिया में दिए गए लिंक ने पहले से ही बताया है, ओएस प्राइमेटिव्स ने लॉक कफॉय से बचने के एक ही कारण के लिए अनुचित व्यवहार प्रदान करना शुरू कर दिया है।

ताला काफिलों बारे में अधिक जानकारी आप Designing Applications for High Performance पर रिक Vicik लेख पढ़ना चाहिए के लिए:

लॉक काफिले

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

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

+0

आप सही हैं, यह स्थिर वस्तु में एक स्थिर वस्तु है, मैंने बहुत तेज़ लिखा है। अब इसे ठीक कर देंगे – Matt

0

Windows और CLR अपना सर्वश्रेष्ठ प्रयास निष्पक्षता प्रतीक्षा की (फीफो आदेश) की गारंटी करने को बनाए रखने। हालांकि, कुछ परिदृश्य हैं जहां लॉक पर इंतजार करने वाले धागे का क्रम बदला जा सकता है, ज्यादातर सतर्क प्रतीक्षा के आसपास घूमते हुए और सभी सीएलआर थ्रेड लॉकिंग थ्रेड को सतर्क स्थिति में रखती है।

सभी व्यावहारिक उद्देश्यों के लिए, आप मान सकते हैं कि आदेश फीफो होगा; हालांकि, इस मुद्दे से अवगत रहें।

1

एक साधारण उदाहरण बताते हैं कि आदेश फीफो

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Diagnostics; 


namespace ConsoleApplication 
{ 
    class Program 
    { 
     private static Info info = new Info(); 

     static void Main(string[] args) 
     { 
      Thread[] t1 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t1[i] = new Thread(info.DoWork); 
      } 

      Thread[] t2 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t2[i] = new Thread(info.Process); 
      } 

      for (int i = 0; i < 5; i++) 
      { 
       t1[i].Start(); 
       t2[i].Start(); 
      } 

      Console.ReadKey(); 
     } 
    } 

    class Info 
    { 
     public object SynObject = new object(); 

     public void DoWork() 
     { 
      Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 

     public void Process() 
     { 
      Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 
    } 
} 
using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Diagnostics; 


namespace ConsoleApplication 
{ 
    class Program 
    { 
     private static Info info = new Info(); 

     static void Main(string[] args) 
     { 
      Thread[] t1 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t1[i] = new Thread(info.DoWork); 
      } 

      Thread[] t2 = new Thread[5]; 
      for (int i = 0; i < 5; i++) 
      { 
       t2[i] = new Thread(info.Process); 
      } 

      for (int i = 0; i < 5; i++) 
      { 
       t1[i].Start(); 
       t2[i].Start(); 
      } 

      Console.ReadKey(); 
     } 
    } 

    class Info 
    { 
     public object SynObject = new object(); 

     public void DoWork() 
     { 
      Debug.Print("DoWork Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Thread Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Thread Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 

     public void Process() 
     { 
      Debug.Print("Process Lock Reached: {0}", Thread.CurrentThread.ManagedThreadId); 
      lock (this.SynObject) 
      { 
       Debug.Print("Process Lock Enter: {0}", Thread.CurrentThread.ManagedThreadId); 
       Thread.Sleep(5000); 
       Debug.Print("Process Lock Exit: {0}", Thread.CurrentThread.ManagedThreadId); 
      } 
     } 
    } 
} 

निष्पादन इस

Process Lock Reached: 15 
Process Lock Enter: 15 
DoWork Lock Reached: 12 
Process Lock Reached: 17 
DoWork Lock Reached: 11 
DoWork Lock Reached: 10 
DoWork Lock Reached: 13 
DoWork Lock Reached: 9 
Process Lock Reached: 18 
Process Lock Reached: 14 
Process Lock Reached: 16 
Process Lock Exit: 15 
Thread Lock Enter: 9 
Thread Lock Exit: 9 
Process Lock Enter: 14 
Process Lock Exit: 14 
Thread Lock Enter: 10 
Thread Lock Exit: 10 
Thread Lock Enter: 11 
Thread Lock Exit: 11 
Process Lock Enter: 16 
Process Lock Exit: 16 
Thread Lock Enter: 12 
Thread Lock Exit: 12 
Process Lock Enter: 17 
Process Lock Exit: 17 
Thread Lock Enter: 13 
Thread Lock Exit: 13 
Process Lock Enter: 18 
Process Lock Exit: 18 

की तरह कुछ आगे बढ़ना होगा यदि आप पहुंच ताला की प्रक्रिया को देखने के सीए के रूप में होने की गारंटी नहीं है कि ताला अलग है दर्ज।

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