What is wrong with this Producer-Consumer sample?

R

Rene Ruppert

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 = new Thread(new ThreadStart(verbrauche));
verbr.Name = "Verbraucher " + (i + 1);
verbr.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 = new Thread(new ThreadStart(verbrauche));
verbr.Name = "Verbraucher " + (i + 1);
verbr.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));
}
}
}
}
}
 
J

Jon Skeet [C# MVP]

Rene said:
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?

You're sleeping while still holding the lock, so anything else waiting
to acquire the lock will have to wait until you've finished sleeping.

See http://www.pobox.com/~skeet/csharp/threads/deadlocks.shtml (about
half way down) for a sample producer/consumer queue.

Jon
 
R

Rene Ruppert

You're sleeping while still holding the lock, so anything else waiting
to acquire the lock will have to wait until you've finished sleeping.

Argl... thanks. That's it.

René
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top