| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 389 人关注过本帖
标题:大家帮忙看看,代码有什么问题:
只看楼主 加入收藏
踏月留香
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2010-7-17
收藏
 问题点数:0 回复次数:2 
大家帮忙看看,代码有什么问题:
这段代码,解决生产者与消费者问题,开始运行还好,到后来,就不行了。出错停止,请帮忙看看,有什么问题:
程序代码:
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();
        }
    }
}
1个生产者和消费者的时候:
图片附件: 游客没有浏览图片的权限,请 登录注册

请看看是为什么啊?

搜索更多相关主题的帖子: 代码 
2010-07-18 09:35
踏月留香
Rank: 1
等 级:新手上路
帖 子:11
专家分:0
注 册:2010-7-17
收藏
得分:0 
搞出来了,换了种方法实现。但就没有上面的方法更符合操作系统里的想法了。
程序代码:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace MyTestDemo
{
  
    class ThreadTest2
    {
        //用Monitor实现生产者与消费者问题
        public class Buffer
        {
            //定义了一个缓冲区
            int[] buffer = new int[3];
            //缓冲区中目前所有的数的个数
            int count = 0;
            //读和写的下标值
            int readIndex = 0, writeIndex = 0;

            //写入缓冲区
            public void SetBuffer(int num)
            {
                lock (this)
                {
                    if (count == buffer.Length)
                    {
                        Console.WriteLine("缓冲区是满的,不能写入");
                        Monitor.Wait(this);
                    }
                    buffer[writeIndex] = num;
                    writeIndex = (writeIndex + 1) % 3;
                    count++;

                    Console.WriteLine("写入缓冲区" + num.ToString());
                    Monitor.Pulse(this);
                }
            }
            //读缓冲区的数
            public void GetBuffer()
            {
                int num1 = 0;
                lock (this)
                {
                    if (count == 0)
                    {
                        Console.WriteLine("缓冲区为空,不能读");
                        Monitor.Wait(this);
                    }
                    num1 = buffer[readIndex];
                    readIndex = (readIndex + 1) % 3;
                    count--;

                    Console.WriteLine("读出缓冲区" + num1.ToString());
                    Monitor.Pulse(this);
                }
            }
        }

        //定义消费者类
        public class Customer
        {
            Buffer myBuffer;
            public Customer(Buffer buffer)
            {
                this.myBuffer = buffer;
            }
            public void Read()
            {
                for (int i = 0; i < 5; i++)
                {
                    myBuffer.SetBuffer(i+1);
                }
            }
        }

        //定义生产者类
        public class Producer
        {
            Buffer myBuffer;
            public Producer(Buffer buffer)
            {
                this.myBuffer = buffer;
            }
            public void Write()
            {
                for (int i = 0; i < 5; i++)
                {
                    myBuffer.GetBuffer();
                }
            }
        }

        public void f()
        {
            Buffer b = new Buffer();
            Producer p = new Producer(b);
            Customer c = new Customer(b);
            Thread producer = new Thread(new ThreadStart(p.Write));
            Thread customer = new Thread(new ThreadStart(c.Read));
            producer.Start();
            customer.Start();
            producer.Join();
            customer.Join();
        }
        public static void Main(string[] args)
        {
            ThreadTest2 t2 = new ThreadTest2();
            t2.f();
        }
    }
}

2010-07-18 13:38
快速回复:大家帮忙看看,代码有什么问题:
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.030703 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved