2016-07-27 97 views
-2

我有以下代碼與單生產者和單個消費者線程,但他們一些如何進入死鎖。我試圖實現類似的功能,如果Java條件變量與C#,但我已經搜索周圍,但沒有發現任何接近它的東西。任何在這方面的幫助將不勝感激。生產者中的死鎖消費者C#有界隊列

`

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

除非這只是一個學習練習,不要打擾寫你自己的隊列。對於單線程使用,使用[隊列](https://msdn.microsoft.com/en-us/library/7977ey2c(v = vs.110).aspx)。對於多線程程序,請使用[BlockingCollection](https://msdn.microsoft.com/en-us/library/dd267312(v = vs.110).aspx)。 –

+0

有關在C#中使用條件變量的示例,請參閱http://stackoverflow.com/questions/15657637/condition-variables-c-net。另外,Stephen Toub在10年前在C#中做了一個阻塞隊列:https://blogs.msdn.microsoft.com/toub/2006/04/12/blocking-queues/ –

+0

是的,它是一個學習練習,你分享的內容是有幫助的在這方面 – pannu

回答

0

我錯過了當過製片人或消費者Monitor.wait後得到通知的伎倆(這一點),他們需重新添加元素進入列表下來是生產者和消費者的正確代碼我用100個生產者線程和10個消費者線程測試了這兩個函數。與隊列大小10,100,1000和這工作正常

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); 
      } 

     } 

    }