Csharp/CSharp Tutorial/Thread/Producer Consumer — различия между версиями
Admin (обсуждение | вклад) м (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