2015-02-15 18 views
8

हाल ही में मैं इस सवाल का एक फोन साक्षात्कारकैसे प्रत्येक थ्रेड क्रमिक रूप से सूची में तत्वों का उपयोग करने के

में पूछा गया था "कहें 3 सरणी एल 1, एल 2 एक ही लंबाई के & L3। तीन धागे तीन सूचियों तक पहुँचने को सूचीबद्ध कर रहे हैं। कहें टी 1 -> एल 1, टी 2 -> एल 2 & टी 3 -> एल 3। यह क्रम में प्रिंट करना चाहिए कि पहले सूची के पहले तत्व के पहले तत्व के पहले तत्व और फिर तीसरी सूची का पहला तत्व। फिर 1 का दूसरा तत्व दूसरी सूची का तत्व और फिर तीसरी सूची का दूसरा तत्व। "

मैंने जवाब दिया कि सेमफोर का उपयोग करके इस समस्या को हल कर सकते हैं, लेकिन जब मैंने सेमाफोर के साथ खुद को कोशिश की तो उचित जवाब नहीं मिला। मेरे नीचे कोड

namespace Semaphore_Example 
{ 
    class Program 
    { 
     static List<int> list1 = new List<int>{ 1, 2, 3, 4, 5 }; 
     static List<int> list2 = new List<int> { 1, 2, 3, 4, 5 }; 
     static List<int> list3 = new List<int> { 1, 2, 3, 4, 5 }; 

     static Semaphore semaphore = new Semaphore(0,3); 
     static SemaphoreSlim _sem = new SemaphoreSlim(3);  

     static void Main(string[] args) 
     { 

      Thread t1 = new Thread(show); 
      Thread t2 = new Thread(show); 
      Thread t3 = new Thread(show); 

      t1.Start(); 
      t2.Start(); 
      t3.Start(); 

      Console.ReadLine(); 
     } 

     static void show() 
     { 
      _sem.Wait(); 

      for (int i = 0; i < 5; i++) 
      { 
       Console.WriteLine(list1[i]); 
       Console.WriteLine(list2[i]); 
       Console.WriteLine(list3[i]); 
      } 

      _sem.Release(); 

     } 
    } 
} 
+0

आपके सभी धागे आपकी सभी सूचियों का आकलन कर रहे हैं - शायद आप सूची को 'शो' का पैरामीटर बनाना चाहते हैं। साथ ही आप शायद सूची में प्रत्येक आइटम के लिए सेमफोर लेना/रिलीज़ करना चाहते हैं, न कि पूरी तरह से सूची के लिए। –

+0

थ्रेड निष्पादन आदेश डिफ़ॉल्ट रूप से अप्रत्याशित है। हालांकि, आप इसे नियंत्रित करने के लिए एक कस्टम थ्रेडपूल लागू कर सकते हैं। – rducom

उत्तर

6

में गलत है अपने आप में एक सेमाफोर अपनी आवश्यकताओं के लिए उपयुक्त नहीं होगा। एक सेमफोर किसी दिए गए संसाधन तक पहुंच को सिंक्रनाइज़ कर सकता है, लेकिन यह उस थ्रेड के बीच ऑर्डर बनाए रखता है जो इसे एक्सेस करने का प्रयास करता है। प्रति MSDN:

फीफो या लिफो जैसे कोई गारंटीकृत आदेश नहीं है, जिसमें अवरुद्ध धागे सेमफोर में प्रवेश करते हैं।

इसके बजाय, मेरा सुझाव है कि आप इंतजार हैंडल, धागा प्रति एक, का एक सेट का उपयोग ऐसी है कि प्रत्येक थ्रेड अपने स्वयं के हैंडल पर इंतजार कर रहा है प्रत्येक तत्व मुद्रण से पहले, और ऐसा करने के बाद अगले थ्रेड हैंडल का संकेत होगा। नीचे दिए गए नमूने को किसी भी सूची (धागे) के साथ काम करने के लिए सामान्यीकृत किया जाता है।

static List<string> list1 = new List<string> { "A1", "A2", "A3", "A4", "A5" }; 
static List<string> list2 = new List<string> { "B1", "B2", "B3", "B4", "B5" }; 
static List<string> list3 = new List<string> { "C1", "C2", "C3", "C4", "C5" }; 

// Add all lists to the array below. 
static List<string>[] lists = new[] { list1, list2, list3 }; 
static AutoResetEvent[] waitHandles; 

static void Main(string[] args) 
{ 
    waitHandles = new AutoResetEvent[lists.Length]; 
    var threads = new Thread[lists.Length]; 

    for (int i = 0; i < lists.Length; i++) 
    { 
     // Initialize a wait handle and thread for each list. 
     int threadIndex = i; 
     waitHandles[i] = new AutoResetEvent(false); 
     threads[i] = new Thread(new ThreadStart(() => show(threadIndex))); 
     threads[i].Start(); 
    } 

    // Signal first thread to start off process. 
    waitHandles[0].Set(); 

    Console.ReadLine(); 
} 

// Method run within each thread. 
static void show(int threadIndex) 
{ 
    // The index of the next thread to signal after printing each element. 
    int nextThreadIndex = (threadIndex + 1) % lists.Length; 

    // Iterate over all elements of current thread's list. 
    foreach (string x in lists[threadIndex]) 
    { 
     // Wait for turn of current thread. 
     waitHandles[threadIndex].WaitOne(); 

     // Print one element. 
     Console.Write(x + " "); 

     // Signal next thread to proceed. 
     waitHandles[nextThreadIndex].Set(); 
    } 

    // Assume all lists are equal in length. 
    // Otherwise, threads might need to keep signalling 
    // even after printing all their elements. 
} 

// Output: A1 B1 C1 A2 B2 C2 A3 B3 C3 A4 B4 C4 A5 B5 C5 
संबंधित मुद्दे