Hi,
I'm trying to implement the Producer-Consumer-Problem in C#.
Below is my code. The problem is, that the buffer always contains only one
element...it seems
that the Thread.Sleep() in the producer and in the consumers make the whole
app sleep
instead of only making the current thread sleep.
Maybe someone can help?
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ErzVerbr
{
class Program
{
private const int MAX_ELEMENTE = 100;
private const int MAX_VERBRAUCHER = 2;
private static int anzElemente = 0;
private static Stack<int> puffer = new Stack<int>(MAX_ELEMENTE);
private static Object elementeVorhanden = "";
private static Object platzFrei = "";
static void Main(string[] args)
{
puffer.Clear();
Thread erz = new Thread(new ThreadStart(erzeuge));
erz.Name = "Erzeuger";
erz.Start();
Thread[] verbr = new Thread[MAX_VERBRAUCHER];
for (int i = 0; i < MAX_VERBRAUCHER; i++)
{
verbr[i] = new Thread(new ThreadStart(verbrauche));
verbr[i].Name = "Verbraucher " + (i + 1);
verbr[i].Start();
}
Console.ReadKey();
}
static public void erzeuge()
{
while (true)
{
lock (elementeVorhanden)
{
if (anzElemente == MAX_ELEMENTE)
{
System.Console.WriteLine("Warte auf Platz...");
Monitor.Wait(platzFrei);
System.Console.WriteLine("Platz verfgbar!");
}
Random rand = new Random();
int element = rand.Next(10, 20);
puffer.Push(element);
Console.WriteLine("Element erzeugt: " +
element + ", Puffer belegt: " +
(anzElemente + 1));
anzElemente++;
Monitor.PulseAll(elementeVorhanden);
Console.WriteLine("Sleep: " + Thread.CurrentThread.Name);
Thread.Sleep(rand.Next(10, 50));
}
}
}
static public void verbrauche()
{
while (true)
{
lock (platzFrei)
{
if (anzElemente == 0)
{
System.Console.WriteLine("Warte auf Elemente...");
Monitor.Wait(elementeVorhanden);
System.Console.WriteLine("Elemente vorhanden!");
}
int element = puffer.Pop();
anzElemente--;
Console.WriteLine("Verbraucht: " + element);
Random rand = new Random();
Monitor.PulseAll(platzFrei);
Console.WriteLine("Sleep: " + Thread.CurrentThread.Name);
Thread.Sleep(rand.Next(2000, 5000));
}
}
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
namespace ErzVerbr
{
class Program
{
private const int MAX_ELEMENTE = 100;
private const int MAX_VERBRAUCHER = 2;
private static int anzElemente = 0;
private static Stack<int> puffer = new Stack<int>(MAX_ELEMENTE);
private static Object elementeVorhanden = "";
private static Object platzFrei = "";
static void Main(string[] args)
{
puffer.Clear();
Thread erz = new Thread(new ThreadStart(erzeuge));
erz.Name = "Erzeuger";
erz.Start();
Thread[] verbr = new Thread[MAX_VERBRAUCHER];
for (int i = 0; i < MAX_VERBRAUCHER; i++)
{
verbr[i] = new Thread(new ThreadStart(verbrauche));
verbr[i].Name = "Verbraucher " + (i + 1);
verbr[i].Start();
}
Console.ReadKey();
}
static public void erzeuge()
{
while (true)
{
lock (elementeVorhanden)
{
if (anzElemente == MAX_ELEMENTE)
{
System.Console.WriteLine("Warte auf Platz...");
Monitor.Wait(platzFrei);
System.Console.WriteLine("Platz verfgbar!");
}
Random rand = new Random();
int element = rand.Next(10, 20);
puffer.Push(element);
Console.WriteLine("Element erzeugt: " +
element + ", Puffer belegt: " +
(anzElemente + 1));
anzElemente++;
Monitor.PulseAll(elementeVorhanden);
Console.WriteLine("Sleep: " + Thread.CurrentThread.Name);
Thread.Sleep(rand.Next(10, 50));
}
}
}
static public void verbrauche()
{
while (true)
{
lock (platzFrei)
{
if (anzElemente == 0)
{
System.Console.WriteLine("Warte auf Elemente...");
Monitor.Wait(elementeVorhanden);
System.Console.WriteLine("Elemente vorhanden!");
}
int element = puffer.Pop();
anzElemente--;
Console.WriteLine("Verbraucht: " + element);
Random rand = new Random();
Monitor.PulseAll(platzFrei);
Console.WriteLine("Sleep: " + Thread.CurrentThread.Name);
Thread.Sleep(rand.Next(2000, 5000));
}
}
}
}
}