2016-07-27 101 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); 
      } 

     } 

    }