Csharp/CSharp Tutorial/Thread/Producer Consumer — различия между версиями

Материал из .Net Framework эксперт
Перейти к: навигация, поиск
м (1 версия)
 
(нет различий)

Текущая версия на 15:20, 26 мая 2010

Consumer Producer with Monitor

<source lang="csharp">using System; using System.Threading; public class MyData {

   private double _pi = 0.0;
   private int _iterations = 0;
   private bool _valueReady = false;
   public void WriteData(int iterations, double val) {
       lock (this) {
           if (_valueReady) {
               Monitor.Wait(this);
           }
           _pi = val;
           _iterations = iterations;
           _valueReady = true;
           Monitor.Pulse(this);
       }
   }
   public void ReadData(out int iterations, out double val) {
       lock (this) {
           if (!_valueReady) {
               Monitor.Wait(this);
           }
           val = _pi;
           iterations = _iterations;
           _valueReady = false;
           Monitor.Pulse(this);
       }
   }

} class MyProducer {

   private MyData _pi;
   private int TotalIters;
   public MyProducer(MyData pi, int iterations) {
       _pi = pi;
       TotalIters = iterations;
   }
   public Thread CreateProducerThread() {
       return new Thread(new ThreadStart(this.calculate));
   }
   private void calculate() {
       int iters = 1;
       do {
           iters += 4;
           _pi.WriteData(iters, iters * 4);
       } while (iters < TotalIters);
   }

} class MyConsumer {

   private MyData _pi;
   private int TotalIters;
   public MyConsumer(MyData pi, int iterations) {
       _pi = pi;
       TotalIters = iterations;
   }
   public Thread CreateConsumerThread() {
       return new Thread(new ThreadStart(this.printValues));
   }
   private void printValues() {
       int iters = new int();
       double pi = new double();
       do {
           _pi.ReadData(out  iters, out pi);
           System.Console.WriteLine("Iters: {0}\tPi:  {1}",iters.ToString(), pi.ToString());
       } while (iters < TotalIters);
   }

} class MainClass {

   static void Main(string[] args) {
       MyData pi = new MyData();
       MyProducer prod = new MyProducer(pi, 100000);
       Thread producerThread = prod.CreateProducerThread();
       MyConsumer cons = new MyConsumer(pi, 100000);
       Thread consumerThread = cons.CreateConsumerThread();
       producerThread.Start();
       consumerThread.Start();
       producerThread.Join();
       consumerThread.Join();
   }

}</source>

Philosopher Example

<source lang="csharp">using System; using System.Threading; class PhilosopherExample {

   public static bool chopStick1Available = true;
   public static bool chopStick2Available = true;
   public static void Main() {
       Thread philosopher1 = new Thread(new ThreadStart(GetChopSticks1));
       Thread philosopher2 = new Thread(new ThreadStart(GetChopSticks2));
       philosopher1.Start();
       philosopher2.Start();
   }
   public static void GetChopSticks1() {
       while (!chopStick1Available) {
           Console.WriteLine("#1 waiting for 1st");
           Thread.Sleep(100);
       }
       Console.WriteLine("#1 got 1st");
       chopStick1Available = false;
       while (!chopStick2Available) {
           Console.WriteLine("#1 waiting for 2nd");
           Thread.Sleep(100); 
       }
       Console.WriteLine("#1 got 2nd");
       chopStick2Available = false;
       Console.WriteLine("#1 uses and releases chopsticks.");
       chopStick1Available = true;
       chopStick2Available = true;
   }
   public static void GetChopSticks2() {
       while (!chopStick2Available) {
           Console.WriteLine("#2 waiting for 1st");
           Thread.Sleep(100);
       }
       Console.WriteLine("#2 got 1st chopstick.");
       chopStick2Available = false;
       while (!chopStick1Available) {
           Console.WriteLine("#2 waiting for 2nd");
           Thread.Sleep(100);
       }
       Console.WriteLine("#2 got 2nd chopstick.");
       chopStick1Available = false;
       Console.WriteLine("#2 uses and releases chopsticks.");
       chopStick1Available = true;
       chopStick2Available = true;
   }

}</source>

Producer and consumer

<source lang="csharp">/* Quote from C# and the .NET Framework by Bob Powell

  • /

using System; using System.Threading; public class Factory {

 private int[]  Widgets = new int[100];
 private int    WidgetIndex = 0;
 private AutoResetEvent NewWidgetEvent = new AutoResetEvent( false );
 protected void Producer( ) {
   while( true ) {
     lock( this ) {
       if( WidgetIndex < 100 ) {
         Widgets[ WidgetIndex ] = 1;
         Console.WriteLine("Widget {0} Produced", WidgetIndex++ );
         NewWidgetEvent.Set( );
       }
     }
     Thread.Sleep( (new Random()).Next( 5 ) * 1000 );
   }
 }
 protected void Consumer( ) {
   while( true ) {
     NewWidgetEvent.WaitOne( );
     int iWidgetIndex = 0;
     lock( this ) {
       iWidgetIndex = --this.WidgetIndex;
       Console.WriteLine("Consuming widget {0}", iWidgetIndex );  
       Widgets[ iWidgetIndex-- ] = 0;
     }
   }
 }
 public void Run( ) {
   for( int i = 0; i < 3; i++ ) {
     Thread producer = new Thread( new ThreadStart( Producer ) );
     producer.Start( );
   }
   for( int i = 0; i < 3; i++ ) {
     Thread consumer = new Thread( new ThreadStart( Consumer ) );
     consumer.Start( );
   }
 }
 public static void Main( ) {
   Factory factory = new Factory( );
   factory.Run( );
 }

}</source>

Widget 0 Produced
Widget 1 Produced
Widget 2 Produced
Consuming widget 2
Widget 2 Produced
Consuming widget 2
Widget 2 Produced
Widget 3 Produced
Consuming widget 3
Consuming widget 2
Widget 2 Produced
Consuming widget 2
Widget 2 Produced
Widget 3 Produced
Consuming widget 3
Consuming widget 2
Widget 2 Produced
Consuming widget 2
^CTerminate batch job (Y/N)? n

Producer/consumer

<source lang="csharp">using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime; using System.Runtime.rupilerServices; using System.Security; using System.Text; using System.Threading; public class MainClass {

   private static Queue<string> sharedQueue = new Queue<string>();    
   public static void Main()
   {
       Thread t1 = new Thread(Producer);
       Thread t2 = new Thread(Consumer);
       t1.Start();
       t2.Start();
       // Join on them:
       t1.Join();
       t2.Join();
   }
   private static void Producer()
   {
       for (int i = 0; i < 2; i++)
       {
           string item = "Item#" + i;
           lock (sharedQueue)
           {
               sharedQueue.Enqueue(item);
               Monitor.Pulse(sharedQueue);
           }
       }
   }
   private static void Consumer()
   {
       for (int i = 0; i < 2; i++)
       {
           string item = null;
           lock (sharedQueue)
           {
               while (sharedQueue.Count == 0)
                   Monitor.Wait(sharedQueue);
               item = sharedQueue.Dequeue();
           }
           Console.WriteLine("Processing item: {0}", item);
       }
   }

}</source>

Processing item: Item#0
Processing item: Item#1