代码GitHub链接:https://github.com/tigmfg/PCProblem_csharp
生产者消费者类
class PCproblem
{
Queue<int> goods = new Queue<int>(); //队列储存物品
int maxBuffer = 3; //最大物品数
int goodNum = 0; //物品编号
Semaphore good = new Semaphore(1, 1); //仓库信号量,生产者和消费者同时只能有一个操作仓库
Semaphore producer = new Semaphore(1, 1);
Semaphore consumer = new Semaphore(0, 1);
bool consumerLocked = true;
bool produserLocked = false;
public void produce()
{
while (true)
{
while (produserLocked == false)
{
Console.WriteLine(Thread.CurrentThread.Name + "准备生产物品");
Thread.Sleep(1000);
good.WaitOne();
if (goods.Count == maxBuffer)
{
Console.WriteLine("当前物品已满,生产者停止生产");
Thread.Sleep(1000);
good.Release();
producer.WaitOne();
produserLocked = true;
break;
}
goodNum++;
goods.Enqueue(goodNum);
Console.WriteLine(Thread.CurrentThread.Name + "生产了物品" + goodNum.ToString());
Console.WriteLine("当前物品数为" + goods.Count.ToString());
Thread.Sleep(1000);
if (consumerLocked)
{
consumerLocked = false;
consumer.Release();
}
good.Release();
}
}
}
public void consume()
{
while (true)
{
while (consumerLocked == false)
{
good.WaitOne();
Console.WriteLine(Thread.CurrentThread.Name + "准备购买物品");
Thread.Sleep(1000);
if (goods.Count == 0)
{
Console.WriteLine("当前物品为空,消费者无法购买");
Thread.Sleep(1000);
good.Release();
consumer.WaitOne();
consumerLocked = true;
break;
}
int thisGood = goods.Dequeue();
Console.WriteLine(Thread.CurrentThread.Name + "购买了物品" + thisGood.ToString());
Console.WriteLine("当前物品数为" + goods.Count.ToString());
Thread.Sleep(1000);
if (produserLocked)
{
produserLocked = false;
producer.Release();
}
good.Release();
}
}
}
}
实例化
static void Main(string[] args)
{
PCproblem good = new PCproblem(); //实例化
//PCProblem2 good = new PCProblem2();
Thread producer1 = new Thread(new ThreadStart(good.produce)); //新建线程
producer1.Name = "生产者1";
Thread producer2 = new Thread(new ThreadStart(good.produce));
producer2.Name = "生产者2";
Thread consumer1 = new Thread(new ThreadStart(good.consume));
consumer1.Name = "消费者1";
Thread consumer2 = new Thread(new ThreadStart(good.consume));
consumer2.Name = "消费者2";
producer1.Start(); //启动线程
consumer1.Start();
producer2.Start();
consumer2.Start();
producer1.Join();
consumer1.Join();
producer2.Join();
consumer2.Join();
}
改进思路
class PCProblem2
{
Queue<int> goods = new Queue<int>(); //物品队列
int goodNum = 0; //物品编号
Semaphore buffer = new Semaphore(1,1); //仓库权限
Semaphore empty = new Semaphore(3, 3); //生产者能够生产的物品数量
Semaphore fill = new Semaphore(0, 3); //消费者可以购买的物品数量
public void produce()
{
while (true)
{
empty.WaitOne(); //等待能够生产物品的信号量
buffer.WaitOne();
goodNum++;
goods.Enqueue(goodNum);
Console.WriteLine(Thread.CurrentThread.Name + "生产者生产了物品" + goodNum.ToString());
Thread.Sleep(1000);
Console.WriteLine("当前物品数为" + goodNum.ToString());
Thread.Sleep(1000);
fill.Release(); //释放有物品被放入信号量
buffer.Release();
}
}
public void consume()
{
while (true)
{
fill.WaitOne(); //等待物品被放入
buffer.WaitOne();
int thisGood = goods.Dequeue();
Console.WriteLine(Thread.CurrentThread.Name + "购买了物品" + thisGood.ToString());
Thread.Sleep(1000);
Console.WriteLine("当前物品数为" + goods.Count.ToString());
Thread.Sleep(1000);
empty.Release(); //可以生产物品信号量
buffer.Release();
}
}
}