修改后的:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
//导入Threading,从而可以进行多线程编程
namespace MyTestDemo
{
//解决操作系统的生产者和消费者问题,其实就是PV问题
//涉及多线程,已经线程之间的同步
public class PEDemo
{
//定义三个变量,分别代表生产者、消费者和资源的数目
private int ProductNum = 0;
private int CustomerNum = 0;
private int ResourceNum = 0;
//metrix是用于互斥的信号量,而empty和full用于同步
public static int metrix = 1;
public static int empty = 0;
public static int
full = 0;
//定义4个栈,用于存放等待线程
private static
Stack<Thread> waiteStackC = new Stack<Thread>();
private static
Stack<Thread> waiteStackP = new Stack<Thread>();
private static Stack<Thread> waiteStackCM = new Stack<Thread>();
private static Stack<Thread> waiteStackPM = new Stack<Thread>();
private static
Thread[] productThread;
private static Thread[] customerThread;
//定义P操作,P是对信号进行减法,如果小于零,那么该线程挂起
public static void P(ref int tag,int num,string type,string tag1)
{
tag--;
if (tag < 0)
{
if (type == "p")
{
Console.WriteLine("生产者" + (num + 1).ToString() + "被挂起");
if (tag1 == "m")
waiteStackPM.Push(Thread.CurrentThread);
else if(tag1=="n")
waiteStackP.Push(Thread.CurrentThread);
Thread.CurrentThread.Suspend();
}
else if (type == "c")
{
Console.WriteLine("消费者" + (num + 1).ToString() + "被挂起");
if (tag1 == "m")
waiteStackCM.Push(Thread.CurrentThread);
else if(tag1=="n")
waiteStackC.Push(Thread.CurrentThread);
Thread.CurrentThread.Suspend();
}
}
}
//定义V操作,V对信号量进行加法,如果加后的值小于等于零,那么唤醒一个线程
public static void V(ref int tag,string type,string tag1)
{
tag++;
if (tag <= 0)
{
if (type == "p")
{
if (tag1 == "m")
{
if (waiteStackCM.Count > 0)
{
Thread thr = waiteStackCM.Pop();
thr.Resume();
}
}
else if (tag1 == "n")
{
if (waiteStackC.Count > 0)
{
Thread thr = waiteStackC.Pop();
thr.Resume();
}
}
Console.WriteLine("一个消费者被唤醒");
}
else if (type == "c")
{
if (tag1 == "m")
{
if (waiteStackPM.Count > 0)
{
Thread thr = waiteStackPM.Pop();
thr.Resume();
}
}
else if (tag1 == "n")
{
if (waiteStackP.Count > 0)
{
Thread thr = waiteStackP.Pop();
thr.Resume();
}
}
Console.WriteLine("一个生产者被唤醒");
}
}
}
//定义内部类
public class Product
{
int num = 0;
public Product(int num)
{
this.num = num;
}
public
void product()
{
while (true)
{
P(ref PEDemo.empty, num, "p","n");
P(ref PEDemo.metrix, num, "p","m");
Console.WriteLine("生产者" + (num + 1).ToString() + "生产一个产品");
V(ref PEDemo.metrix, "p","m");
V(ref PEDemo.full, "p","n");
}
}
}
public class Customer
{
int num = 0;
public Customer(int num)
{
this.num = num;
}
public void customer()
{
while (true)
{
P(ref PEDemo.full, num, "c","n");
P(ref PEDemo.metrix, num, "c","m");
Console.WriteLine("消费者" + (num + 1).ToString() + "消费一个产品");
V(ref PEDemo.metrix, "c","m");
V(ref PEDemo.empty, "c","n");
}
}
}
//用于初始化
public PEDemo()
{
try
{
Console.WriteLine("生产者数目为?");
ProductNum=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("消费者数目为?");
CustomerNum=Convert.ToInt32(Console.ReadLine());
Console.WriteLine("资源数目为?");
ResourceNum=Convert.ToInt32(Console.ReadLine());
//初始化full信号量
full = ResourceNum;
productThread=new Thread[ProductNum];
customerThread=new Thread[CustomerNum];
for (int i = 0; i < ProductNum; i++)
{
Product p = new Product(i);
productThread[i] = new Thread(new ThreadStart(p.product));
productThread[i].Start();
}
for (int i = 0; i < CustomerNum; i++)
{
Customer c = new Customer(i);
customerThread[i] = new Thread(new ThreadStart(c.customer));
customerThread[i].Start();
}
}
catch(FormatException ex)
{
Console.WriteLine("您输入的格式有误");
}
}
public static void Main(string[] args)
{
PEDemo pe = new PEDemo();
}
}
}