生产者消费者C#中的死锁有界队列

时间:2016-07-27 15:47:44

标签: c# multithreading deadlock

我有以下代码与单个生产者和一个消费者线程,但他们有一些如何进入死锁。我试图实现类似的功能,如果java条件变量与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);
                }
            }

        }

    }
}

}

`

1 个答案:

答案 0 :(得分: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);
            }

        }

    }