• 0

Concurrency


Question

Below is the code to send a graphic through 3 panels from one panel to the next in order, panels 1 then 2 then 3, which is easy enough with 2 panels but when you add 3,4,5 panels this is where the problem starts the object should pass from left to right from panel to panel but instead after the first panel it runs in both the second and the third panel at the same time, and not in order from panel 1,2,3 instead i get 1, 2 and 3.. how do you determine the order of the panels for the object to travel...


using System;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;
using System.Collections;
using System.Data;
using System.Drawing;
public class Form1 : Form
{
private Container components = null;
private ButtonPanelThread p1;
private Button btn1;
private WaitPanelThread p2, p3;
private Thread thread1, thread2, thread3;
private Semaphore semaphore;
private Buffer buffer;
private Thread semThread;
private Thread buffThread;
private Panel pnl1, pnl2, pnl3;
public Form1()
{
InitializeComponent();

semaphore = new Semaphore();
buffer = new Buffer();
p1 = new ButtonPanelThread(new Point(40, 10), 120, true, pnl1, Color.Blue, semaphore, buffer, btn1);
p2 = new WaitPanelThread(new Point(5, 10), 200, true, pnl2, Color.White, semaphore, buffer);
p3 = new WaitPanelThread(new Point(5, 10), 200, true, pnl3, Color.White, semaphore, buffer);
semThread = new Thread(new ThreadStart(semaphore.Start));
buffThread = new Thread(new ThreadStart(buffer.Start));
thread1 = new Thread(new ThreadStart(p1.Start));
thread2 = new Thread(new ThreadStart(p2.Start));
thread3 = new Thread(new ThreadStart(p3.Start));
this.Closing += new CancelEventHandler(this.Form1_Closing);
semThread.Start();
buffThread.Start();
thread1.Start();
thread2.Start();
thread3.Start();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.pnl1 = new System.Windows.Forms.Panel();
this.btn1 = new System.Windows.Forms.Button();
this.pnl2 = new System.Windows.Forms.Panel();
this.pnl3 = new System.Windows.Forms.Panel();
this.pnl1.SuspendLayout();
this.SuspendLayout();
//
// pnl1
//
this.pnl1.BackColor = System.Drawing.Color.White;
this.pnl1.Controls.Add(this.btn1);
this.pnl1.Location = new System.Drawing.Point(29, 200);
this.pnl1.Name = "pnl1";
this.pnl1.Size = new System.Drawing.Size(260, 30);
this.pnl1.TabIndex = 0;
//
// btn1
//
this.btn1.BackColor = System.Drawing.Color.Pink;
this.btn1.Location = new System.Drawing.Point(0, 0);
this.btn1.Name = "btn1";
this.btn1.Size = new System.Drawing.Size(30, 30);
this.btn1.TabIndex = 0;
this.btn1.UseVisualStyleBackColor = false;
//
// pnl2
//
this.pnl2.BackColor = System.Drawing.Color.White;
this.pnl2.Location = new System.Drawing.Point(295, 200);
this.pnl2.Name = "pnl2";
this.pnl2.Size = new System.Drawing.Size(260, 30);
this.pnl2.TabIndex = 1;
//
// pnl3
//
this.pnl3.BackColor = System.Drawing.Color.White;
this.pnl3.Location = new System.Drawing.Point(561, 200);
this.pnl3.Name = "pnl3";
this.pnl3.Size = new System.Drawing.Size(260, 30);
this.pnl3.TabIndex = 2;
//
// Form1
//
this.BackColor = System.Drawing.Color.LightGray;
this.ClientSize = new System.Drawing.Size(861, 462);
this.Controls.Add(this.pnl1);
this.Controls.Add(this.pnl2);
this.Controls.Add(this.pnl3);
this.Name = "Form1";
this.Text = "Test";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
this.pnl1.ResumeLayout(false);
this.ResumeLayout(false);
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
// Environment is a System class.
// Kill off all threads on exit.
Environment.Exit(Environment.ExitCode);
}
}// end class form1
public class Buffer
{
private Color objectColor;
private bool empty = true;
public void Read(ref Color objectColor)
{
lock (this)
{
// Check whether the buffer is empty.
if (empty)
Monitor.Wait(this);
empty = true;
objectColor = this.objectColor;
Monitor.Pulse(this);
}
}
public void Write(Color objectColor)
{
lock (this)
{
// Check whether the buffer is full.
if (!empty)
Monitor.Wait(this);
empty = false;
this.objectColor = objectColor;
Monitor.Pulse(this);
}
}
public void Start()
{
}
}// end class Buffer
public class Semaphore
{
private int count = 0;
public void Wait()
{
lock (this)
{
while (count == 0)
Monitor.Wait(this);
count = 0;
}
}
public void Signal()
{
lock (this)
{
count = 1;
Monitor.Pulse(this);
}
}
public void Start()
{
}
}// end class Semaphore
public class ButtonPanelThread
{
private Point origin;
private int delay;
private Panel panel;
private bool westEast;
private Color colour;
private Point obj;
private int xDelta;
private int yDelta;
private Semaphore semaphore;
private Buffer buffer;
private Button btn;
private bool locked = true;
public ButtonPanelThread(Point origin, int delay, bool westEast, Panel panel,Color colour, Semaphore semaphore, Buffer buffer, Button btn)
{
this.origin = origin;
this.delay = delay;
this.westEast = westEast;
this.panel = panel;
this.colour = colour;
this.obj = origin;
this.panel.Paint += new PaintEventHandler(this.panel_Paint);
this.xDelta = westEast ? +10 : -10;
this.yDelta = 0;
this.semaphore = semaphore;
this.buffer = buffer;
this.btn = btn;
this.btn.Click += new System.EventHandler(this.btn_Click);
}
private void btn_Click(object sender,
System.EventArgs e)
{
locked = !locked;
this.btn.BackColor = locked ? Color.Pink : Color.LightGreen;
lock (this)
{
if (!locked)
Monitor.Pulse(this);
}
}
public void Start()
{
Color signal = Color.Red;
Thread.Sleep(delay);
for (int k = 1; k <= 1; k++)
{
this.zeroObject();
panel.Invalidate();
lock (this)
{
while (locked)
{
Monitor.Wait(this);
}
}
for (int i = 1; i <= 20; i++)
{
this.moveObject(xDelta, yDelta);
Thread.Sleep(delay);
panel.Invalidate();
}
semaphore.Wait();
buffer.Write(this.colour);
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroObject()
{
obj.X = origin.X;
obj.Y = origin.Y;
}
private void moveObject(int xDelta, int yDelta)
{
obj.X += xDelta; obj.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
g.FillRectangle(brush, obj.X, obj.Y, 10, 10);
brush.Dispose(); // Dispose graphics resources.
g.Dispose(); //
}
}// end class ButtonPanelThread
public class WaitPanelThread
{
private Point origin;
private int delay;
private Panel panel;
private bool westEast;
private Color colour;
private Point obj;
private int xDelta;
private int yDelta;
private Semaphore semaphore;
private Buffer buffer;
public WaitPanelThread(Point origin, int delay, bool westEast, Panel panel, Color colour, Semaphore semaphore, Buffer buffer)
{
this.origin = origin;
this.delay = delay;
this.westEast = westEast;
this.panel = panel;
this.colour = colour;
this.obj = origin;
this.panel.Paint += new PaintEventHandler(this.panel_Paint);
this.xDelta = westEast ? +10 : -10;
this.yDelta = 0;
this.semaphore = semaphore;
this.buffer = buffer;
}
public void Start()
{
//Thread.Sleep(delay);
this.colour = Color.White;
for (int k = 1; k <= 10; k++)
{
semaphore.Signal();
this.zeroObject();
buffer.Read(ref this.colour);
for (int i = 1; i <= 23; i++)
{
panel.Invalidate();
this.moveObject(xDelta, yDelta);
Thread.Sleep(delay);
}
this.colour = Color.White;
panel.Invalidate();
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroObject()
{
obj.X = origin.X;
obj.Y = origin.Y;
}
private void moveObject(int xDelta, int yDelta)
{
obj.X += xDelta; obj.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
g.FillRectangle(brush, obj.X, obj.Y, 10, 10);
brush.Dispose(); // Dispose graphics resources.
g.Dispose(); //
}
}// end class WaitPanelThread
public class TheOne
{
public static void Main()//
{
Application.Run(new Form1());
}
}// end class TheOne
[/CODE]

Link to comment
Share on other sites

13 answers to this question

Recommended Posts

  • 0

It's still just as hard to tell what this code does at it was in your previous question. Your "Semaphores" and "Buffers" are custom objects and not really standard synchronisation primitives, at least the "Semaphore" doesn't look like much of a real semaphore to me, and I've never heard of a "Buffer" as a synchronization primitive either. It's not clear what these things do, how you're supposed to use them, and what you're trying to achieve. Since you don't explain much and this seems like homework anyway, it'd probably simpler if you just posted the assignment verbatim here.

Link to comment
Share on other sites

  • 0

this is a scaled down version to make it simple, i just want to pass the object (graphic) from panel to panel, there are 4 panels in total, the reason for the semaphores and buffers is that no two objects can occupy the same panel at the same time, this is the reason why i'm using them to check to see if the panel is empty or full then pass the object on to the next panel, like a car going round a race track but think of it as 3 cars trying to enter the track but no two cars can occupy the same part of the track. its meant to be an example of concurrency using semaphores and buffers to pass the graphic through 4 waitpanels, but i just get deadlock or all 4 panels show the graphic at the same time, i not sure how many semaphores/ buffers i need and to how to set this up without getting deadlock

Link to comment
Share on other sites

  • 0

It looks like your "Semaphores" are really just locks. Then you simply need one per panel and only one thread will be able to access it at a time. What are your "buffers" supposed to do and how could you get deadlocks?

Link to comment
Share on other sites

  • 0

that's correct they are meant to lock the panels if there occupied by a graphic. buffers are to check if the panels are empty or full, and queue the graphic ready for the panel to become empty, in some respect create a queue system

Link to comment
Share on other sites

  • 0

that's correct they are meant to lock the panels if there occupied by a graphic. buffers are to check if the panels are empty or full, and queue the graphic ready for the panel to become empty, in some respect create a queue system

Geez, methinks you need to sort out your terminology or something...

Link to comment
Share on other sites

  • 0

Geez, methinks you need to sort out your terminology or something...

i think your comments aren't very helpful or informative, i'm trying to learn and understand, and your just being an idiot troll.. if you don't have any helpful insight then don't comment fool. we all have to learn and start somewhere.

Link to comment
Share on other sites

  • 0

that's correct they are meant to lock the panels if there occupied by a graphic. buffers are to check if the panels are empty or full, and queue the graphic ready for the panel to become empty, in some respect create a queue system

Looks like you're using two locks where you only need one. A semaphore is already in itself a queue that ensures exclusive access to a resource and allows other threads to queue up, waiting for it to become available. Once a thread has acquired the semaphore, it can do whatever it wants with the resource without needing to acquire or queue up on anything else. You don't need anything more than one semaphore per panel.

Unless I'm missing something, it's very simple:

N panels that can only be accessed by one thread at a time

M threads trying to access these panels concurrently

=

N semaphores, one per panel

Then assuming the panels are disposed sequentially, the algorithm per thread becomes:


while there are panels left:
Acquire next panel (its semaphore)
Release current panel
[/CODE]

Why wouldn't that work?

Link to comment
Share on other sites

  • 0

ok thx for your help i'll give this a try,. if i'm using more then one thread and need to set up a thread priority wouldn't a buffer help. the idea is trying to create pseudo-concurrency. wouldn't i need one semaphore per panel and one buffer per object (graphic/car) as i'm actually handling upto 4 cars on the track in the main program..

Link to comment
Share on other sites

  • 0

ok thx for your help i'll give this a try,. if i'm using more then one thread and need to set up a thread priority wouldn't a buffer help. the idea is trying to create pseudo-concurrency. wouldn't i need one semaphore per panel and one buffer per object (graphic/car) as i'm actually handling upto 4 cars on the track in the main program..

the example i've been given looks like this, but i've been asked to expand on it by adding a track with 4 panels a right, down, left, up direction panel and 2 more button panel which allow access into the track, each object entering the track must wait for the panel to be empty before if can access the track which means no 2 objects can occupy the same panel. from my understanding i need many semaphores and buffers but every time I've tried to do this i get nothing no movement from panel to panel, i've even tried to draw this out as a UML diagram to help to work out the process.. but i can't seem to expand example below using both the semaphores and buffers



using System;
using System.Windows.Forms;
using System.Threading;
using System.ComponentModel;
using System.Collections;
using System.Data;
using System.Drawing;
public class Form1 : Form
{
private Container components = null;
private ButtonPanelThread p1;
private Button btn1;
private WaitPanelThread p2;
private Thread thread1, thread2;
private Semaphore semaphore;
private Buffer buffer;
private Thread semThread;
private Thread buffThread;
private Panel pnl1, pnl2;
public Form1()
{
InitializeComponent();

semaphore = new Semaphore();
buffer = new Buffer();
p1 = new ButtonPanelThread(new Point(40, 10), 120, true, pnl1, Color.Blue, semaphore, buffer, btn1);
p2 = new WaitPanelThread(new Point(5, 10), 200, true, pnl2, Color.White, semaphore, buffer);
semThread = new Thread(new ThreadStart(semaphore.Start));
buffThread = new Thread(new ThreadStart(buffer.Start));
thread1 = new Thread(new ThreadStart(p1.Start));
thread2 = new Thread(new ThreadStart(p2.Start));
this.Closing += new CancelEventHandler(this.Form1_Closing);
semThread.Start();
buffThread.Start();
thread1.Start();
thread2.Start();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.pnl1 = new System.Windows.Forms.Panel();
this.btn1 = new System.Windows.Forms.Button();
this.pnl2 = new System.Windows.Forms.Panel();
this.pnl1.SuspendLayout();
this.SuspendLayout();
//
// pnl1
//
this.pnl1.BackColor = System.Drawing.Color.White;
this.pnl1.Controls.Add(this.btn1);
this.pnl1.Location = new System.Drawing.Point(29, 200);
this.pnl1.Name = "pnl1";
this.pnl1.Size = new System.Drawing.Size(260, 30);
this.pnl1.TabIndex = 0;
//
// btn1
//
this.btn1.BackColor = System.Drawing.Color.Pink;
this.btn1.Location = new System.Drawing.Point(0, 0);
this.btn1.Name = "btn1";
this.btn1.Size = new System.Drawing.Size(30, 30);
this.btn1.TabIndex = 0;
this.btn1.UseVisualStyleBackColor = false;
//
// pnl2
//
this.pnl2.BackColor = System.Drawing.Color.White;
this.pnl2.Location = new System.Drawing.Point(295, 200);
this.pnl2.Name = "pnl2";
this.pnl2.Size = new System.Drawing.Size(260, 30);
this.pnl2.TabIndex = 1;
//
// Form1
//
this.BackColor = System.Drawing.Color.LightGray;
this.ClientSize = new System.Drawing.Size(606, 424);
this.Controls.Add(this.pnl1);
this.Controls.Add(this.pnl2);
this.Name = "Form1";
this.Text = "Test";
this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
this.pnl1.ResumeLayout(false);
this.ResumeLayout(false);
}
private void Form1_Closing(object sender, CancelEventArgs e)
{
// Environment is a System class.
// Kill off all threads on exit.
Environment.Exit(Environment.ExitCode);
}
}// end class form1
public class Buffer
{
private Color objectColor;
private bool empty = true;
public void Read(ref Color objectColor)
{
lock (this)
{
// Check whether the buffer is empty.
if (empty)
Monitor.Wait(this);
empty = true;
objectColor = this.objectColor;
Monitor.Pulse(this);
}
}
public void Write(Color objectColor)
{
lock (this)
{
// Check whether the buffer is full.
if (!empty)
Monitor.Wait(this);
empty = false;
this.objectColor = objectColor;
Monitor.Pulse(this);
}
}
public void Start()
{
}
}// end class Buffer
public class Semaphore
{
private int count = 0;
public void Wait()
{
lock (this)
{
while (count == 0)
Monitor.Wait(this);
count = 0;
}
}
public void Signal()
{
lock (this)
{
count = 1;
Monitor.Pulse(this);
}
}
public void Start()
{
}
}// end class Semaphore
public class ButtonPanelThread
{
private Point origin;
private int delay;
private Panel panel;
private bool westEast;
private Color colour;
private Point obj;
private int xDelta;
private int yDelta;
private Semaphore semaphore;
private Buffer buffer;
private Button btn;
private bool locked = true;
public ButtonPanelThread(Point origin, int delay, bool westEast, Panel panel,Color colour, Semaphore semaphore, Buffer buffer, Button btn)
{
this.origin = origin;
this.delay = delay;
this.westEast = westEast;
this.panel = panel;
this.colour = colour;
this.obj = origin;
this.panel.Paint += new PaintEventHandler(this.panel_Paint);
this.xDelta = westEast ? +10 : -10;
this.yDelta = 0;
this.semaphore = semaphore;
this.buffer = buffer;
this.btn = btn;
this.btn.Click += new System.EventHandler(this.btn_Click);
}
private void btn_Click(object sender, System.EventArgs e)
{
locked = !locked;
this.btn.BackColor = locked ? Color.Pink : Color.LightGreen;
lock (this)
{
if (!locked)
Monitor.Pulse(this);
}
}
public void Start()
{
Color signal = Color.Red;
Thread.Sleep(delay);
for (int k = 1; k <= 20; k++)
{
this.zeroObject();
panel.Invalidate();
lock (this)
{
while (locked)
{
Monitor.Wait(this);
}
}
for (int i = 1; i <= 20; i++)
{
this.moveObject(xDelta, yDelta);
Thread.Sleep(delay);
panel.Invalidate();
}
semaphore.Wait();
buffer.Write(this.colour);
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroObject()
{
obj.X = origin.X;
obj.Y = origin.Y;
}
private void moveObject(int xDelta, int yDelta)
{
obj.X += xDelta; obj.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
g.FillRectangle(brush, obj.X, obj.Y, 10, 10);
brush.Dispose(); // Dispose graphics resources.
g.Dispose(); //
}
}// end class ButtonPanelThread
public class WaitPanelThread
{
private Point origin;
private int delay;
private Panel panel;
private bool westEast;
private Color colour;
private Point obj;
private int xDelta;
private int yDelta;
private Semaphore semaphore;
private Buffer buffer;
public WaitPanelThread(Point origin, int delay, bool westEast, Panel panel, Color colour, Semaphore semaphore, Buffer buffer)
{
this.origin = origin;
this.delay = delay;
this.westEast = westEast;
this.panel = panel;
this.colour = colour;
this.obj = origin;
this.panel.Paint += new PaintEventHandler(this.panel_Paint);
this.xDelta = westEast ? +10 : -10;
this.yDelta = 0;
this.semaphore = semaphore;
this.buffer = buffer;
}
public void Start()
{
//Thread.Sleep(delay);
this.colour = Color.White;
for (int k = 1; k <= 10; k++)
{
semaphore.Signal();
this.zeroObject();
buffer.Read(ref this.colour);
for (int i = 1; i <= 23; i++)
{
panel.Invalidate();
this.moveObject(xDelta, yDelta);
Thread.Sleep(delay);
}
this.colour = Color.White;
panel.Invalidate();
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroObject()
{
obj.X = origin.X;
obj.Y = origin.Y;
}
private void moveObject(int xDelta, int yDelta)
{
obj.X += xDelta; obj.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
g.FillRectangle(brush, obj.X, obj.Y, 10, 10);
brush.Dispose(); // Dispose graphics resources.
g.Dispose(); //
}
}// end class WaitPanelThread
public class TheOne
{
public static void Main()//
{
Application.Run(new Form1());
}
}// end class TheOne
[/CODE]

Link to comment
Share on other sites

  • 0

I don't have the time to try to figure out what you're supposed to do and how the various pieces of this code are supposed to fit together. It's not even clear if the problem is about concurrency at all. If you can narrow down your question to something more specific I'd be glad to help.

Link to comment
Share on other sites

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.