L
Leonardo Hyppolito
Hello!
I am trying to implement a program that uses Threads. I chose the producers
and consumers scenario. The producers put a "product" (which is an int
number) in a shared storage place of one position. The consumers must
consume all the products that are put in the storage place.
The user of the program enters how many products it will be produced, and
also, how many producers and consumers (each one in a separate thread) there
will be.
My program is not working ok... When I choose a high number of producers
(let's say 5), and a low number of consumers (let's say 2), it doesn't work
well.. I can't spot where the problem is.
Here is the code... Thanks in advance for any help !
Leo Hyppolito
---
using System;
using System.Threading;
namespace TesteProdCons
{
// can hold 1 product at a time (buffer of 1 position)
public class Storage
{
// represents the product (a delay in miliseconds)
// -1 is "empty"
private int p;
// actual product number
private int n;
// number of products (max) to be produced
private int nMax;
public int Product
{
get
{
lock(this)
{
// if it's empty, wait
if(p == -1)
{
Console.WriteLine("CONSUMER [" + Thread.CurrentThread.Name + "] has to
wait (storage is empty)");
Monitor.Wait(this);
}
// read the product
int ret = p;
// empty the buffer (so that it can receive a new product)
p = -1;
// signal the next pending thread to move on
Monitor.Pulse(this);
// return the product value
return ret;
}
}
set
{
lock(this)
{
// if it has a product, wait
if(p != -1)
{
Console.WriteLine("PRODUCER [" + Thread.CurrentThread.Name + "] has to
wait (storage is full)");
Monitor.Wait(this);
}
// store the product
p = value;
// write information on screen
Console.WriteLine("++ [" + Thread.CurrentThread.Name + "] produces n."
+ Number + ": " + p);
// increment the actual product number
Number = Number + 1;
// signal the next pending thread to move on
Monitor.Pulse(this);
}
}
}
public int Number
{
get {return n;}
set {n = value;}
}
public int MaxNumber
{
get
{
lock(this)
{
return nMax;
}
}
set {nMax = value;}
}
// constructor
public Storage(int i)
{
p = -1;
Number = 1;
MaxNumber = i;
}
}
public class Producer
{
// a reference to the storage
private Storage a;
// seed for the random
private int seed;
// constructor
public Producer(Storage arm, int s)
{
a = arm;
seed = s;
}
public void produce()
{
Random r = new Random(seed);
while(a.Number <= a.MaxNumber)
{
// get a random integer (from 0 to 2 seconds)
int prod = r.Next(2001);
// store the product
a.Product = prod;
// rest for a while...
Thread.Sleep(500);
}
}
}
public class Consumer
{
// a reference to the storage
Storage a;
// constructor
public Consumer(Storage arm)
{
a = arm;
}
public void consume()
{
while(true)
{
// get the product value
int prod = a.Product;
// "consume" the product (pauses for the product's miliseconds)
Thread.Sleep(prod);
Console.WriteLine("-- [" + Thread.CurrentThread.Name + "] consumed " +
prod);
}
}
}
class Class1
{
static void Main(string[] args)
{
int numProducts;
int numProducers;
int numConsumers;
Console.Write("Max number of products: ");
numProducts = Int32.Parse(Console.ReadLine());
Console.Write("Number of producers: ");
numProducers = Int32.Parse(Console.ReadLine());
Console.Write("Numero of consumers: ");
numConsumers = Int32.Parse(Console.ReadLine());
Storage a = new Storage(numProducts);
Producer[] prod = new Producer[numProducers];
Consumer[] cons = new Consumer[numConsumers];
Thread[] tProd = new Thread[numProducers];
Thread[] tCons = new Thread[numConsumers];
Random r = new Random();
// create the producers objects and threads
for(int i = 0; i < numProducers; i++)
{
prod = new Producer(a, r.Next(999999));
tProd = new Thread(new ThreadStart(prod.produce));
tProd.Name = "p" + (i+1);
}
// create the consumers objects and threads
for(int i = 0; i < numConsumers; i++)
{
cons = new Consumer(a);
tCons = new Thread(new ThreadStart(cons.consume));
tCons.Name = "c" + (i+1);
}
// start the threads
foreach (Thread t in tProd) {t.Start();}
foreach (Thread t in tCons) {t.Start();}
Console.WriteLine("Storage, producers and consumers created!");
}
}
}
I am trying to implement a program that uses Threads. I chose the producers
and consumers scenario. The producers put a "product" (which is an int
number) in a shared storage place of one position. The consumers must
consume all the products that are put in the storage place.
The user of the program enters how many products it will be produced, and
also, how many producers and consumers (each one in a separate thread) there
will be.
My program is not working ok... When I choose a high number of producers
(let's say 5), and a low number of consumers (let's say 2), it doesn't work
well.. I can't spot where the problem is.
Here is the code... Thanks in advance for any help !
Leo Hyppolito
---
using System;
using System.Threading;
namespace TesteProdCons
{
// can hold 1 product at a time (buffer of 1 position)
public class Storage
{
// represents the product (a delay in miliseconds)
// -1 is "empty"
private int p;
// actual product number
private int n;
// number of products (max) to be produced
private int nMax;
public int Product
{
get
{
lock(this)
{
// if it's empty, wait
if(p == -1)
{
Console.WriteLine("CONSUMER [" + Thread.CurrentThread.Name + "] has to
wait (storage is empty)");
Monitor.Wait(this);
}
// read the product
int ret = p;
// empty the buffer (so that it can receive a new product)
p = -1;
// signal the next pending thread to move on
Monitor.Pulse(this);
// return the product value
return ret;
}
}
set
{
lock(this)
{
// if it has a product, wait
if(p != -1)
{
Console.WriteLine("PRODUCER [" + Thread.CurrentThread.Name + "] has to
wait (storage is full)");
Monitor.Wait(this);
}
// store the product
p = value;
// write information on screen
Console.WriteLine("++ [" + Thread.CurrentThread.Name + "] produces n."
+ Number + ": " + p);
// increment the actual product number
Number = Number + 1;
// signal the next pending thread to move on
Monitor.Pulse(this);
}
}
}
public int Number
{
get {return n;}
set {n = value;}
}
public int MaxNumber
{
get
{
lock(this)
{
return nMax;
}
}
set {nMax = value;}
}
// constructor
public Storage(int i)
{
p = -1;
Number = 1;
MaxNumber = i;
}
}
public class Producer
{
// a reference to the storage
private Storage a;
// seed for the random
private int seed;
// constructor
public Producer(Storage arm, int s)
{
a = arm;
seed = s;
}
public void produce()
{
Random r = new Random(seed);
while(a.Number <= a.MaxNumber)
{
// get a random integer (from 0 to 2 seconds)
int prod = r.Next(2001);
// store the product
a.Product = prod;
// rest for a while...
Thread.Sleep(500);
}
}
}
public class Consumer
{
// a reference to the storage
Storage a;
// constructor
public Consumer(Storage arm)
{
a = arm;
}
public void consume()
{
while(true)
{
// get the product value
int prod = a.Product;
// "consume" the product (pauses for the product's miliseconds)
Thread.Sleep(prod);
Console.WriteLine("-- [" + Thread.CurrentThread.Name + "] consumed " +
prod);
}
}
}
class Class1
{
static void Main(string[] args)
{
int numProducts;
int numProducers;
int numConsumers;
Console.Write("Max number of products: ");
numProducts = Int32.Parse(Console.ReadLine());
Console.Write("Number of producers: ");
numProducers = Int32.Parse(Console.ReadLine());
Console.Write("Numero of consumers: ");
numConsumers = Int32.Parse(Console.ReadLine());
Storage a = new Storage(numProducts);
Producer[] prod = new Producer[numProducers];
Consumer[] cons = new Consumer[numConsumers];
Thread[] tProd = new Thread[numProducers];
Thread[] tCons = new Thread[numConsumers];
Random r = new Random();
// create the producers objects and threads
for(int i = 0; i < numProducers; i++)
{
prod = new Producer(a, r.Next(999999));
tProd = new Thread(new ThreadStart(prod.produce));
tProd.Name = "p" + (i+1);
}
// create the consumers objects and threads
for(int i = 0; i < numConsumers; i++)
{
cons = new Consumer(a);
tCons = new Thread(new ThreadStart(cons.consume));
tCons.Name = "c" + (i+1);
}
// start the threads
foreach (Thread t in tProd) {t.Start();}
foreach (Thread t in tCons) {t.Start();}
Console.WriteLine("Storage, producers and consumers created!");
}
}
}