Csharp/CSharp Tutorial/Thread/Producer Consumer — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Версия 15:31, 26 мая 2010
Содержание
Consumer Producer with Monitor
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();
}
}
Philosopher Example
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;
}
}
Producer and consumer
/*
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( );
}
}
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
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);
}
}
}
Processing item: Item#0 Processing item: Item#1