现在的位置: 首页 > 综合 > 正文

用C#多线程解决生产者-消费者问题

2012年05月23日 ⁄ 综合 ⁄ 共 3486字 ⁄ 字号 评论关闭
    生产者-消费者问题是说明多线程同步&互斥的经典问题,也是最近偶操作系统老师的一道编程作业。
问题描述:一个仓库可以存放K件物品。生产者每生产一件产品,将产品放入仓库,仓库满了就停止生产。消费者每次从仓库中去一件物品,然后进行消费,仓库空时就停止消费。

     在C#的System.Threading命名空间中,有可以用来解决这个问题的对象(Monitor、Mutex等),下面是一个我写的控制台程序,包括了大多数要用到的方法(但并不完全满足原问题的要求的,想想要怎么改动一下吧):

//生产者-消费者问题
//by BodeSmile

using System;
using System.Threading;

namespace Producer_Consumer
{
    
class Producer_Consumer
    
{
        
public const int N = 100;                        //缓冲区中的槽数目
        public static Mutex mutex;                        //控制对临界区的访问
        public static int empty = N;                    //计数缓冲区的空槽数目
        public static int full = 0;                        //计数缓冲区的满槽数目
 
        
public static int [] buffer = new int[N];        //模拟缓冲区
        public static int cnt=0;                        //记录模拟缓冲区的起始位置

        
public void Insert_Item(int tp)                    //将(新)数据项放入缓冲区中
        {
            buffer[(cnt
+full)%N]=tp;
        }


        
public int Remove_Item()                        //将(新)数据项放入缓冲区中
        {
            
int tp=buffer[cnt];
            cnt
=(cnt+1)%N;
            
return tp;
        }


        
public void Down(ref int tp)
        
{
            Monitor.Enter(
this);                        //以下操作是不可打断的
            while(tp<=0)
            
{
                Monitor.Pulse(
this);
                Monitor.Wait(
this);
            }

            tp
--;
            Monitor.Exit(
this);                            //以上操作是不可打断的
        }


        
public void Up(ref int tp)
        
{
            Monitor.Enter(
this);                        //以下操作是不可打断的
            tp++;
            Monitor.Exit(
this);                            //以上操作是不可打断的
        }


        
public int Produce_Item()                        //产生放在模拟缓冲区中的一些数据
        {
            
int tp=100;
            Thread.Sleep(
50);
            
return tp;
        }


        
public void Consume_Item(int tp)                //处理数据项
        {
            Thread.Sleep(
50);
        }


        
public void Producer()                            //生产者
        {
            
int item=0;

            
while(true)
            
{
                item
=Produce_Item();
                Down(
ref empty);
                mutex.WaitOne();
                Insert_Item(item);
                mutex.ReleaseMutex();
                Up(
ref full);
            }

        }


        
public void Consumer()                            //消费者
        {
            
int item=0;

            
while(true)
            
{
                Down(
ref full);
                mutex.WaitOne();
                item
=Remove_Item();
                mutex.ReleaseMutex();
                Up(
ref empty);
                Consume_Item(item);
            }

        }


        
/// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        //[STAThread]
        static void Main(string[] args)
        
{
            
int i=0,j=0;

            mutex
=new Mutex(false,"MUTEX");

            Producer_Consumer e 
= new Producer_Consumer();

            ThreadStart ps 
= new ThreadStart(e.Producer);
            Thread p 
= new Thread(ps);
            p.Start();                                
//启动生产者线程

            ThreadStart cs 
= new ThreadStart(e.Consumer);
            Thread c 
= new Thread(cs);
            c.Start();                                
//启动消费者线程

            
while(true)
            
{
                j
=full;
                
if(i!=j)                            //缓冲区改变时输出缓冲区状态
                {
                    Console.WriteLine(j.ToString());
                    i
=j;
                }

            }


            Console.ReadLine();
        }

    }

}

最后再放上完成图形界面后的一张效果图,呵呵!

抱歉!评论已关闭.