首页 > 编程 > C# > 正文

基于C#实现的多生产者多消费者同步问题实例

2020-01-24 02:26:04
字体:
来源:转载
供稿:网友

本文实例讲述了基于C#实现的多生产者多消费者同步问题,分享给大家供大家参考之用。具体代码如下:

// 多个生产者和多个消费者,能生产n个产品的情况using System;using System.Threading;public class HoldIntegerSynchronized{ private int[] buffer; //缓冲区 private int occupiedBufferCount = 0; private int readPosition = 0 , writePosition = 0; //下一个读到的位置和写到的位置 public HoldIntegerSynchronized(int capacity){ buffer = new int[capacity]; }  public int BufferSize{ get{  return buffer.Length; } } public int Buffer{ get{  int bufferCopy;  // 加锁  lock(this){  while(occupiedBufferCount == 0){ //多个消费者,所以此处改用while   Console.WriteLine(Thread.CurrentThread.Name + " tries to read. ");   DisplayState("Buffer Empty. " + Thread.CurrentThread.Name + " waits.");   Monitor.Wait(this);    // 为临界区之外等待的生产者放行,让他来"生产"   // 一直到生产者生产结束,调用了Monitor.PauseAll()   // 才能继续执行下去,此时,消费者自动重新获得this的锁  }  --occupiedBufferCount;  bufferCopy = buffer[readPosition];  readPosition = (readPosition + 1) % buffer.Length;    DisplayState(Thread.CurrentThread.Name + " reads " + bufferCopy);  // 通知,让等待的 生产者线程 进入Started状态,如果生产者处于临界区之外,这句话执行完后他仍然在临界区之外  Monitor.PulseAll(this);  // 释放锁  }//lock  return bufferCopy; } set{  // 加锁  lock(this){  while(occupiedBufferCount == buffer.Length){   Console.WriteLine(Thread.CurrentThread.Name + " tries to write. ");   DisplayState("Buffer Full. " + Thread.CurrentThread.Name + " waits.");   Monitor.Wait(this);    // 为临界区之外等待消费者放行,让他来"消费"   // 一直到消费者调用了Monitor.Pause()   // 才能继续执行下去,此时,生产者自动重新获得this的锁  }  buffer[writePosition] = value;  ++occupiedBufferCount;   writePosition = (writePosition + 1) % buffer.Length;  DisplayState(Thread.CurrentThread.Name + " writes " + value);  // 通知,让Wait状态的 消费者 进入Started状态,如果消费者处于临界区之外,这句话执行完后他仍然在临界区之外  Monitor.PulseAll(this);  // 释放锁  } } } public void DisplayState(string operation){ Console.Write("{0,-35}",operation); for(int i = 0; i < BufferSize; i++ ){  int a = readPosition;  int b = writePosition;  if( a <= i && i < b) {  Console.Write("{0,-9}",buffer[i]);  }else if( b < a && !( b <= i && i < a ) ){  Console.Write("{0,-9}",buffer[i]);  }else if( occupiedBufferCount == BufferSize){  Console.Write("{0,-9}",buffer[i]);  }else{  Console.Write("{0,-9}","");  } } Console.WriteLine("{0}/r/n",occupiedBufferCount); }}class Producer{ private HoldIntegerSynchronized sharedLocation; private Random randomSleepTime; public Producer(HoldIntegerSynchronized shared,Random random){ sharedLocation = shared; randomSleepTime = random; }  public void Produce(){ for (int count=0; count<3; count++) {  Thread.Sleep(randomSleepTime.Next(1,2000));  sharedLocation.Buffer = randomSleepTime.Next(5,10); } Console.WriteLine(Thread.CurrentThread.Name + " done producing./r/nTerminating " + Thread.CurrentThread.Name + "./r/n"); }}class Consumer{ private HoldIntegerSynchronized sharedLocation; private Random randomSleepTime; public Consumer(HoldIntegerSynchronized shared,Random random){ sharedLocation = shared; randomSleepTime = random; } public void Consume(){ int sum = 0; for (int count=0; count<4; count++) {  Thread.Sleep(randomSleepTime.Next(1,2000));  sum += sharedLocation.Buffer; } Console.WriteLine(Thread.CurrentThread.Name + " read values totaling:" + sum + "/r/nTerminating " + Thread.CurrentThread.Name + "."); } }class SharedCell{ static void Main(string[] args){ HoldIntegerSynchronized holdInteger = new HoldIntegerSynchronized(5); Random random = new Random(); Thread[] producerThreads = new Thread[4]; Thread[] consumerThreads = new Thread[3]; Console.Write("{0,-35}","Operation"); for(int i = 0;i < holdInteger.BufferSize;i++){  Console.Write("{0,-9}","Elem " + i); } Console.WriteLine("Occupied Count/r/n"); for(int i = 0; i < producerThreads.Length;i++){  Producer producer = new Producer(holdInteger,random);  producerThreads[i] = new Thread(new ThreadStart(producer.Produce));  producerThreads[i].Name = "Producer No." + i; } for(int i = 0; i < consumerThreads.Length;i++){  Consumer consumer = new Consumer(holdInteger,random);  consumerThreads[i] = new Thread(new ThreadStart(consumer.Consume));  consumerThreads[i].Name = "Consumer No." + i; } for(int i = 0; i < producerThreads.Length;i++){  producerThreads[i].Start(); } for(int i = 0; i < consumerThreads.Length;i++){  consumerThreads[i].Start(); } }}

希望本文所述对大家C#程序设计的学习有所帮助。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表