首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

OS中 生产消费者有关问题(同步有关问题)请老师们提点 提点下 小弟先谢了!

2012-01-30 
OS中 生产消费者问题(同步问题)请老师们提点 提点下 小弟先谢了!!!!我先在的问题是 当资源栈满时这时生产

OS中 生产消费者问题(同步问题)请老师们提点 提点下 小弟先谢了!!!!
我先在的问题是 当资源栈满时这时生产者线程就会等待.空时消费者线程也会等待.. 但是在最后等待的线程不会再被唤醒..我用的是datagridview存放每一个操作者的步骤.但就是不会在显示等待的线程应该被唤醒再继续操作..
请老师指点指点谢谢

using   System;
using   System.Collections.Generic;
using   System.ComponentModel;
using   System.Data;
using   System.Drawing;
using   System.Text;
using   System.Windows.Forms;
using   System.Threading;
namespace   spc_w1
{
        public   partial   class   Form1   :   Form
        {
                public   Form1()
                {
                        InitializeComponent();
                }

                private   void   Form1_Load(object   sender,   EventArgs   e)
                {
                        SharedControl();//   用来生成线程 和执行的.
                        sreen1(ShareArea.Dt);
                }
                public   void   sreen1(DataTable   dt)
                {
                        dataGridView1.AutoGenerateColumns   =   false;
                        dataGridView1.Columns[ "z1 "].DataPropertyName   =   "1 ";
                        dataGridView1.Columns[ "z2 "].DataPropertyName   =   "2 ";
                        dataGridView1.Columns[ "z3 "].DataPropertyName   =   "3 ";
                        dataGridView1.Columns[ "z4 "].DataPropertyName   =   "4 ";
                        dataGridView1.Columns[ "z5 "].DataPropertyName   =   "5 ";
                        dataGridView1.Columns[ "z6 "].DataPropertyName   =   "6 ";
                        dataGridView1.Columns[ "z7 "].DataPropertyName   =   "7 ";
                        dataGridView1.Columns[ "z8 "].DataPropertyName   =   "8 ";
                        dataGridView1.Columns[ "z9 "].DataPropertyName   =   "9 ";
                       
                        dataGridView1.DataSource   =   dt;
                }
                private   void   SharedControl()


                {
                        Thread[]   ProThreads   =   new   Thread[3];
                        Thread[]   ConThreads   =   new   Thread[2];
                 
                        int   i   =   0;
                        for   (i   =   0;   i   <   3;   i++)
                        {
                              producer   Pro   =   new   producer();
                              ProThreads[i]=new   Thread(new   ThreadStart(Pro.BufferPNum));
                              ProThreads[i].Name   =   "Pro "   +   i.ToString();
                        }
                        for   (i   =   0;   i   <   2;   i++)
                        {
                                Consumer   Con   =   new   Consumer();
                                ConThreads[i]   =   new   Thread(new   ThreadStart(Con.BufferCNum));
                                ConThreads[i].Name   =   "Con "   +   i.ToString();
                        }
                        for   (i   =   0;   i   <   2;   i++)
                        {
                                ConThreads[i].Start();
                               
                        }
                        for   (i   =   0;   i   <   3;   i++)
                        {
                                ProThreads[i].Start();
                               
                        }
                 

                }




        }
        public   class   ShareArea//资源区 
        {
    //它们全是静态的 
                public   static   int[]   Buffer;//缓冲区
                public   static   int   BufferSize;//缓冲区大小
                public   static   int   BufferCounts;//资源数量
                public   static   int   readP;//消费指针
                public   static   int   writeP;//生产指针
                public   static   DataTable   Dt;//用来显示动作的dt
                static     ShareArea()
                {
                        Buffer   =new   int[5];
                        BufferSize   =   5;
                        BufferCounts   =   0;
                        readP   =   0;
                        writeP   =   0;
                          Dt   =   new   DataTable();
                        Dt.Columns.Add( "1 ",   typeof(string));
                        Dt.Columns.Add( "2 ",   typeof(string));
                        Dt.Columns.Add( "3 ",   typeof(string));
                        Dt.Columns.Add( "4 ",   typeof(string));
                        Dt.Columns.Add( "5 ",   typeof(string));
                        Dt.Columns.Add( "6 ",   typeof(string));
                        Dt.Columns.Add( "7 ",   typeof(string));
                        Dt.Columns.Add( "8 ",   typeof(string));
                        Dt.Columns.Add( "9 ",   typeof(string));
                }
     
                public   static   void   print(string   a)//显示操作的每一行
                {
                        DataRow   dr;
                        dr   =   Dt.NewRow();
                        dr[ "1 "]   =   a;


                        dr[ "2 "]   =   BufferCounts;
                        dr[ "3 "]   =   writeP.ToString();
                        dr[ "4 "]   =   readP.ToString();
                        int   i=0;
                        int   k=0;
                        for   (i   =   0;   i   <   BufferSize;   i++)
                        {
                                k=5+i;
                                if   (Buffer[i]   > 0)
                                        dr[k.ToString()]   =   Buffer[i];
                                else   dr[k.ToString()]   =   " ";
                        }
                        Dt.Rows.Add(dr);
                }


        }
        public   class   producer//   生产者
        {
                public   static   int   z=1;
                private   Random   randomSleepTime;
                public   producer()
                {
                        randomSleepTime   =   new   Random();
                }
                public   void   bufferP()//生产
                {
                        lock   (this)
                        {
                              while   (ShareArea.BufferCounts   ==   ShareArea.BufferSize)
                                {
                                        //不能生产,BUFFER是满的
                                        string   ss   =   " ";
                                        ss   +=   "Buffer是满的 ";


                                        ss   +=   Thread.CurrentThread.Name;
                                        ss   +=   "不能生产!等待.. ";
                                        ShareArea.print(ss);
                                        Monitor.Wait(this);
                                }

                                ShareArea.BufferCounts++;
                                ShareArea.Buffer[ShareArea.writeP]   =   z;

                                ShareArea.writeP   =   (ShareArea.writeP   +   1)   %   ShareArea.BufferSize;
                                //生产成功。
                                //打印出有界缓冲区的全部内容,当前指针位置和生产者/消费者的标识符.
                                string   ss1   =   " ";
                                ss1   +=   Thread.CurrentThread.Name;
                                ss1   +=   "生产一个资源 "   +   z.ToString();
                                z++;
                                ShareArea.print(ss1);
                                Monitor.PulseAll(this);
                        }
   
                }
                public   void   BufferPNum()
                {
                        int   i   =   0;
                        for   (i   =   0;   i   <   3;i++   )
                        {
                                bufferP();
                                Thread.Sleep(randomSleepTime.Next(1,   2000));  
                        }


                        string   sk3   =   Thread.CurrentThread.Name   +   "生产完毕.. ";
                        ShareArea.print(sk3);
                }
        }
        public   class   Consumer//消费者
        {
                private   Random   randomSleepTime;
                public   Consumer()
                {
                        randomSleepTime   =   new   Random();
                }
                public   void   bufferC()//消费
                {
                        int   bf   =   0;
                        lock   (this)
                        {
                                while   (ShareArea.BufferCounts   ==   0)
                                {
                                        //不能消费,生产者没生产出产品;
                                        string   ss   =   " ";
                                        ss   +=   "Buffer是空的 ";
                                        ss   +=   Thread.CurrentThread.Name;
                                        ss   +=   "不能消费!等待.. ";
                                        ShareArea.print(ss);
                                        Monitor.Wait(this);
                                }

                                ShareArea.BufferCounts--;
                                bf   =   ShareArea.Buffer[ShareArea.readP];
                                ShareArea.readP   =   (ShareArea.readP   +   1)   %   ShareArea.BufferSize;


                             
                                //消费成功。
                                //打印出有界缓冲区的全部内容,当前指针位置和生产者/消费者的标识符.
                                string   ss2   =   " ";
                                ss2   +=   Thread.CurrentThread.Name;
                                ss2   +=   "消费一个资源 "   +   bf.ToString();
                                ShareArea.print(ss2);
                                Monitor.PulseAll(this);
                        }
                       
                }
                public   void   BufferCNum()
                {
                        int   i   =   0;
                        for   (i   =   0;   i   <4;   i++)
                        {
                                Thread.Sleep(randomSleepTime.Next(1,   2000));
                                bufferC();
                        }
                        string   sk2   =   Thread.CurrentThread.Name+ "消费完毕.. ";
                        ShareArea.print(sk2);
                }
        }

}

[解决办法]
你的 Monitor.Wait(this); 和 Monitor.PulseAll(this); 都在一个线程里,如果程序走到Monitor.Wait(this)就被阻塞在那里,永远也执行不到Monitor.PulseAll(this),也就是说此线程永远不会被唤醒.


Monitor.Wait(this); 和 Monitor.PulseAll(this) 通常是用在不同线程之间传递共享资源信息的.

热点排行