2016-07-27 7 views
-2

Ich habe den folgenden Code mit einzelnen Produzenten und einem einzelnen Consumer-Thread, aber die sie einige wie in Dead-Lock geraten. Ich versuche, ähnliche Funktionalität zu erreichen, wenn Java bedingte Variable mit C#, aber ich habe herumgesucht, aber keine Sache in der Nähe gefunden. Jede Hilfe in dieser Hinsicht wäre sehr willkommen.Dead Lock in Producer Consumer C# Eingeschlossene Warteschlange

`

private List<T> coffeeBevrages; 
    private volatile int count; 
    private int max; 
    private int consumed = 0; 
    static Semaphore pool; 

    public Queue() 
    { 
     max = 10; 
     pool = new Semaphore(0, max); 
     count = 0; 
     coffeeBevrages = new List<T>(); 
    } 
    public void busyAdd(T name) 
    { 
     while (!add(name)) Console.WriteLine("producesr busy"); 
    } 
    public void busyRemove(T name) 
    { 
     while (!remove(name)) Console.WriteLine("consumer busy"); 
    } 
    private bool add(T name) 
    { 
     lock(this) 
     { 
      if (count < max) 
      { 
       count++; 
       coffeeBevrages.Add(name); 
       return true; 
      } 
      else 
       return false; 

     } 

    } 
    private bool remove(T name) 
    { 
     lock (this) 
     { 
      if (count > 0) 
      { 

       count--; 
       Console.WriteLine(coffeeBevrages.Remove(name)); 
       consumed++; 
       Console.WriteLine(consumed); 
       return true; 
      } 
      else 
       return false; 

     } 

    } 
    public void sleepAdd(T name) 
    { 
     Console.WriteLine("Hey......################"); 
     #region locking code 
     lock (this) 
     { 
      if (count < max) 
      { 
       count++; 
       consumed++; 
       Console.WriteLine("Produced : " + consumed); 
       Console.WriteLine("Here notification p " + count);                                        
       coffeeBevrages.Add(name); 
       Monitor.PulseAll(this); 
      } 
      else 
      { 
       while (count == max) 
       { 
        Console.WriteLine("Here " + count); 
        Monitor.Wait(this,100); 
       } 
      } 
     #endregion 
     } 

    } 
    public void sleepremove(T name) 
    { 
     lock (this) 
     { 
      if (count > 0) 
      { 

       Console.WriteLine("Here notification c " + count); 
       count--; 
       Monitor.PulseAll(this); 
      } 
      else 
      { 
       while (count == 0) 
       { 
        Console.WriteLine("Here" + count); 
        Monitor.Wait(this,100); 
       } 
      } 

     } 

    } 
} 

}

`

+0

Wenn dies nicht nur eine Lernübung ist, nicht die Mühe schreiben Sie Ihre eigene Warteschlange. Verwenden Sie für Singlethread-Verwendung [Warteschlange ] (https://msdn.microsoft.com/en-us/library/7977ey2c (v = vs.110) .aspx). Verwenden Sie für Multithread-Programme [BlockingCollection] (https://msdn.microsoft.com/en-us/library/dd267312 (v = vs.110) .aspx). –

+0

Ein Beispiel zur Verwendung von Bedingungsvariablen in C# finden Sie unter http://stackoverflow.com/questions/15657637/condition-variables-c-net. Außerdem hat Stephen Toub in C# vor 10 Jahren eine blockierende Warteschlange: https://blogs.msdn.microsoft.com/toub/2006/04/12/blocking-queues/ –

+0

ja es ist eine Lernübung der Inhalt, den Sie geteilt haben, ist hilfreich in dieser Hinsicht – pannu

Antwort

0

ich den Trick verpasst, wenn jemals ein Produzent oder Verbraucher nach Monitor.Wait benachrichtigt, (das) sie benötigen, um das Element in das wiederholen Hinzufügen list down ist der richtige Code für Producer und Consumer Ich habe diese beiden Funktionen mit 100 Producer-Threads und 10 Consumer-Threads getestet. mit Warteschlange Größe 10,100,1000 und das hat gut funktioniert

public void sleepAdd(T name) 
    { 
     #region locking code 
     lock (this) 
     { 
      if (count < max) 
      { 
       count++; 

       coffeeBevrages.Add(name); 
       Monitor.PulseAll(this); 
      } 
      else 
      { 
       while (count == max) 
       { 
        Console.WriteLine("Producer to Sleep"); 
        Monitor.Wait(this); 
       } 
       sleepAdd(name); 
      } 
     #endregion 
     } 

    } 
    public void sleepremove(T name) 
    { 
     lock (this) 
     { 
      if (count > 0) 
      { 
       consumed++; 
       Console.WriteLine(consumed); 
       count--; 
       Monitor.PulseAll(this); 
      } 
      else 
      { 
       while (count == 0) 
       { 
        Console.WriteLine("Consumer to Sleep"); 
        Monitor.Wait(this); 
       } 
       sleepremove(name); 
      } 

     } 

    } 
Verwandte Themen