生产者-消费者问题是说明多线程同步&互斥的经典问题,也是最近偶操作系统老师的一道编程作业。 
在C#的System.Threading命名空间中,有可以用来解决这个问题的对象(Monitor、Mutex等),下面是一个我写的控制台程序,包括了大多数要用到的方法(但并不完全满足原问题的要求的,想想要怎么改动一下吧): //生产者-消费者问题
//生产者-消费者问题 
 //by BodeSmile
//by BodeSmile 
 
 
 using System;
using System; 
 using System.Threading;
using System.Threading; 
 
 
 namespace Producer_Consumer
namespace Producer_Consumer 
 {
{ 
 class Producer_Consumer
    class Producer_Consumer 
 {
    { 
 public const int N = 100;                        //缓冲区中的槽数目
        public const int N = 100;                        //缓冲区中的槽数目 
 public static Mutex mutex;                        //控制对临界区的访问
        public static Mutex mutex;                        //控制对临界区的访问 
 public static int empty = N;                    //计数缓冲区的空槽数目
        public static int empty = N;                    //计数缓冲区的空槽数目 
 public static int full = 0;                        //计数缓冲区的满槽数目
        public static int full = 0;                        //计数缓冲区的满槽数目 
 
  
 public static int [] buffer = new int[N];        //模拟缓冲区
        public static int [] buffer = new int[N];        //模拟缓冲区 
 public static int cnt=0;                        //记录模拟缓冲区的起始位置
        public static int cnt=0;                        //记录模拟缓冲区的起始位置 
 
 
 public void Insert_Item(int tp)                    //将(新)数据项放入缓冲区中
        public void Insert_Item(int tp)                    //将(新)数据项放入缓冲区中 
 {
        { 
 buffer[(cnt+full)%N]=tp;
            buffer[(cnt+full)%N]=tp; 
 }
        } 
 
 
 public int Remove_Item()                        //将(新)数据项放入缓冲区中
        public int Remove_Item()                        //将(新)数据项放入缓冲区中 
 {
        { 
 int tp=buffer[cnt];
            int tp=buffer[cnt]; 
 cnt=(cnt+1)%N;
            cnt=(cnt+1)%N; 
 return tp;
            return tp; 
 }
        } 
 
 
 public void Down(ref int tp)
        public void Down(ref int tp) 
 {
        { 
 Monitor.Enter(this);                        //以下操作是不可打断的
            Monitor.Enter(this);                        //以下操作是不可打断的 
 while(tp<=0)
            while(tp<=0) 
 {
            { 
 Monitor.Pulse(this);
                Monitor.Pulse(this); 
 Monitor.Wait(this);
                Monitor.Wait(this); 
 }
            } 
 tp--;
            tp--; 
 Monitor.Exit(this);                            //以上操作是不可打断的
            Monitor.Exit(this);                            //以上操作是不可打断的 
 }
        } 
 
 
 public void Up(ref int tp)
        public void Up(ref int tp) 
 {
        { 
 Monitor.Enter(this);                        //以下操作是不可打断的
            Monitor.Enter(this);                        //以下操作是不可打断的 
 tp++;
            tp++; 
 Monitor.Exit(this);                            //以上操作是不可打断的
            Monitor.Exit(this);                            //以上操作是不可打断的 
 }
        } 
 
 
 public int Produce_Item()                        //产生放在模拟缓冲区中的一些数据
        public int Produce_Item()                        //产生放在模拟缓冲区中的一些数据 
 {
        { 
 int tp=100;
            int tp=100; 
 Thread.Sleep(50);
            Thread.Sleep(50); 
 return tp;
            return tp; 
 }
        } 
 
 
 public void Consume_Item(int tp)                //处理数据项
        public void Consume_Item(int tp)                //处理数据项 
 {
        { 
 Thread.Sleep(50);
            Thread.Sleep(50); 
 }
        } 
 
 
 public void Producer()                            //生产者
        public void Producer()                            //生产者 
 {
        { 
 int item=0;
            int item=0; 
 
 
 while(true)
            while(true) 
 {
            { 
 item=Produce_Item();
                item=Produce_Item(); 
 Down(ref empty);
                Down(ref empty); 
 mutex.WaitOne();
                mutex.WaitOne(); 
 Insert_Item(item);
                Insert_Item(item); 
 mutex.ReleaseMutex();
                mutex.ReleaseMutex(); 
 Up(ref full);
                Up(ref full); 
 }
            } 
 }
        } 
 
 
 public void Consumer()                            //消费者
        public void Consumer()                            //消费者 
 {
        { 
 int item=0;
            int item=0; 
 
 
 while(true)
            while(true) 
 {
            { 
 Down(ref full);
                Down(ref full); 
 mutex.WaitOne();
                mutex.WaitOne(); 
 item=Remove_Item();
                item=Remove_Item(); 
 mutex.ReleaseMutex();
                mutex.ReleaseMutex(); 
 Up(ref empty);
                Up(ref empty); 
 Consume_Item(item);
                Consume_Item(item); 
 }
            } 
 }
        } 
 
 
 /// <summary>
        /// <summary> 
 /// 应用程序的主入口点。
        /// 应用程序的主入口点。 
 /// </summary>
        /// </summary> 
 //[STAThread]
        //[STAThread] 
 static void Main(string[] args)
        static void Main(string[] args) 
 {
        { 
 int i=0,j=0;
            int i=0,j=0; 
 
 
 mutex=new Mutex(false,"MUTEX");
            mutex=new Mutex(false,"MUTEX"); 
 
 
 Producer_Consumer e = new Producer_Consumer();
            Producer_Consumer e = new Producer_Consumer(); 
 
 
 ThreadStart ps = new ThreadStart(e.Producer);
            ThreadStart ps = new ThreadStart(e.Producer); 
 Thread p = new Thread(ps);
            Thread p = new Thread(ps); 
 p.Start();                                //启动生产者线程
            p.Start();                                //启动生产者线程 
 
 
 ThreadStart cs = new ThreadStart(e.Consumer);
            ThreadStart cs = new ThreadStart(e.Consumer); 
 Thread c = new Thread(cs);
            Thread c = new Thread(cs); 
 c.Start();                                //启动消费者线程
            c.Start();                                //启动消费者线程 
 
 
 while(true)
            while(true) 
 {
            { 
 j=full;
                j=full; 
 if(i!=j)                            //缓冲区改变时输出缓冲区状态
                if(i!=j)                            //缓冲区改变时输出缓冲区状态 
 {
                { 
 Console.WriteLine(j.ToString());
                    Console.WriteLine(j.ToString()); 
 i=j;
                    i=j; 
 }
                } 
 }
            } 
 
 
 Console.ReadLine();
            Console.ReadLine(); 
 }
        } 
 }
    } 
 }
} 
 
 
最后再放上完成图形界面后的一张效果图,呵呵!
 
问题描述:一个仓库可以存放K件物品。生产者每生产一件产品,将产品放入仓库,仓库满了就停止生产。消费者每次从仓库中去一件物品,然后进行消费,仓库空时就停止消费。 
在C#的System.Threading命名空间中,有可以用来解决这个问题的对象(Monitor、Mutex等),下面是一个我写的控制台程序,包括了大多数要用到的方法(但并不完全满足原问题的要求的,想想要怎么改动一下吧):
 //生产者-消费者问题
//生产者-消费者问题  //by BodeSmile
//by BodeSmile  
  using System;
using System;  using System.Threading;
using System.Threading;  
  namespace Producer_Consumer
namespace Producer_Consumer  {
{  class Producer_Consumer
    class Producer_Consumer  {
    {  public const int N = 100;                        //缓冲区中的槽数目
        public const int N = 100;                        //缓冲区中的槽数目  public static Mutex mutex;                        //控制对临界区的访问
        public static Mutex mutex;                        //控制对临界区的访问  public static int empty = N;                    //计数缓冲区的空槽数目
        public static int empty = N;                    //计数缓冲区的空槽数目  public static int full = 0;                        //计数缓冲区的满槽数目
        public static int full = 0;                        //计数缓冲区的满槽数目  
   public static int [] buffer = new int[N];        //模拟缓冲区
        public static int [] buffer = new int[N];        //模拟缓冲区  public static int cnt=0;                        //记录模拟缓冲区的起始位置
        public static int cnt=0;                        //记录模拟缓冲区的起始位置  
  public void Insert_Item(int tp)                    //将(新)数据项放入缓冲区中
        public void Insert_Item(int tp)                    //将(新)数据项放入缓冲区中  {
        {  buffer[(cnt+full)%N]=tp;
            buffer[(cnt+full)%N]=tp;  }
        }  
  public int Remove_Item()                        //将(新)数据项放入缓冲区中
        public int Remove_Item()                        //将(新)数据项放入缓冲区中  {
        {  int tp=buffer[cnt];
            int tp=buffer[cnt];  cnt=(cnt+1)%N;
            cnt=(cnt+1)%N;  return tp;
            return tp;  }
        }  
  public void Down(ref int tp)
        public void Down(ref int tp)  {
        {  Monitor.Enter(this);                        //以下操作是不可打断的
            Monitor.Enter(this);                        //以下操作是不可打断的  while(tp<=0)
            while(tp<=0)  {
            {  Monitor.Pulse(this);
                Monitor.Pulse(this);  Monitor.Wait(this);
                Monitor.Wait(this);  }
            }  tp--;
            tp--;  Monitor.Exit(this);                            //以上操作是不可打断的
            Monitor.Exit(this);                            //以上操作是不可打断的  }
        }  
  public void Up(ref int tp)
        public void Up(ref int tp)  {
        {  Monitor.Enter(this);                        //以下操作是不可打断的
            Monitor.Enter(this);                        //以下操作是不可打断的  tp++;
            tp++;  Monitor.Exit(this);                            //以上操作是不可打断的
            Monitor.Exit(this);                            //以上操作是不可打断的  }
        }  
  public int Produce_Item()                        //产生放在模拟缓冲区中的一些数据
        public int Produce_Item()                        //产生放在模拟缓冲区中的一些数据  {
        {  int tp=100;
            int tp=100;  Thread.Sleep(50);
            Thread.Sleep(50);  return tp;
            return tp;  }
        }  
  public void Consume_Item(int tp)                //处理数据项
        public void Consume_Item(int tp)                //处理数据项  {
        {  Thread.Sleep(50);
            Thread.Sleep(50);  }
        }  
  public void Producer()                            //生产者
        public void Producer()                            //生产者  {
        {  int item=0;
            int item=0;  
  while(true)
            while(true)  {
            {  item=Produce_Item();
                item=Produce_Item();  Down(ref empty);
                Down(ref empty);  mutex.WaitOne();
                mutex.WaitOne();  Insert_Item(item);
                Insert_Item(item);  mutex.ReleaseMutex();
                mutex.ReleaseMutex();  Up(ref full);
                Up(ref full);  }
            }  }
        }  
  public void Consumer()                            //消费者
        public void Consumer()                            //消费者  {
        {  int item=0;
            int item=0;  
  while(true)
            while(true)  {
            {  Down(ref full);
                Down(ref full);  mutex.WaitOne();
                mutex.WaitOne();  item=Remove_Item();
                item=Remove_Item();  mutex.ReleaseMutex();
                mutex.ReleaseMutex();  Up(ref empty);
                Up(ref empty);  Consume_Item(item);
                Consume_Item(item);  }
            }  }
        }  
  /// <summary>
        /// <summary>  /// 应用程序的主入口点。
        /// 应用程序的主入口点。  /// </summary>
        /// </summary>  //[STAThread]
        //[STAThread]  static void Main(string[] args)
        static void Main(string[] args)  {
        {  int i=0,j=0;
            int i=0,j=0;  
  mutex=new Mutex(false,"MUTEX");
            mutex=new Mutex(false,"MUTEX");  
  Producer_Consumer e = new Producer_Consumer();
            Producer_Consumer e = new Producer_Consumer();  
  ThreadStart ps = new ThreadStart(e.Producer);
            ThreadStart ps = new ThreadStart(e.Producer);  Thread p = new Thread(ps);
            Thread p = new Thread(ps);  p.Start();                                //启动生产者线程
            p.Start();                                //启动生产者线程  
  ThreadStart cs = new ThreadStart(e.Consumer);
            ThreadStart cs = new ThreadStart(e.Consumer);  Thread c = new Thread(cs);
            Thread c = new Thread(cs);  c.Start();                                //启动消费者线程
            c.Start();                                //启动消费者线程  
  while(true)
            while(true)  {
            {  j=full;
                j=full;  if(i!=j)                            //缓冲区改变时输出缓冲区状态
                if(i!=j)                            //缓冲区改变时输出缓冲区状态  {
                {  Console.WriteLine(j.ToString());
                    Console.WriteLine(j.ToString());  i=j;
                    i=j;  }
                }  }
            }  
  Console.ReadLine();
            Console.ReadLine();  }
        }  }
    }  }
}  
 最后再放上完成图形界面后的一张效果图,呵呵!
 
                    
                     
                    
                 
                    
                 


 
     
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号