我的英语不是很好,写得非常简单,所以提前对不起......
我见过类似的问题,但没有使用图形。
我要做的是设置一个简单的电路显示,其中一个点从ButtonPanel开始,当点击按钮并且绿色时,将释放更多的点,我使用信号量和缓冲区来控制它是否去进入下一个面板,想法是点将围绕面板做一个电路(顺时针运动),直到(现在)硬编码限制使原点停止发出点。
我觉得我对缓冲区和信号量的性质感到困惑,但是就像我对它们所做的那样阅读,我仍然无法让它按照我想要的方式行事......
系统离开第一个面板时,会同时在所有4个WaitPanelThreads中设置一个点,这不是我想要的。
我尝试过添加更多信号量,但这没有任何好处。我构建了自己的信号量和缓冲区,试图了解它们正在做什么,但我无法继续这个程序。我花了很多年的时间试图让系统正常运行,但是我很难过,如果由于我的英语问题而没有多大意义,请问我会更好地说出来。
下面是我为此编写的所有代码,我很确定问题是我构建WaitPanelThreads的地方。任何帮助表示赞赏,我正在尝试自学。
菲利克斯
编辑:我还必须评论下面的代码如果你将它闯入visual studio,那么你可能需要包含两个引用,如果你想看看它是如何设置的话
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, p4, p5;
private Thread thread1, thread2, thread3, thread4, thread5;
private Semaphore semaphore, semaphore1;
private Buffer buffer, buffer1;
private Thread semThread, semThread1;
private Thread buffThread, buffThread1;
private Panel pnl1, pnl2, pnl3, pnl4, pnl5;
public Form1()
{
InitializeComponent();
semaphore = new Semaphore();
semaphore1 = new Semaphore();
buffer = new Buffer();
buffer1 = new Buffer();
p1 = new ButtonPanelThread(new Point(40, 10),
30, true, pnl1,
Color.Blue,
semaphore,
buffer,
btn1);
p2 = new WaitPanelThread(new Point(10, 10),
80, false, 2, pnl2,
Color.White,
semaphore,
buffer);
p3 = new WaitPanelThread(new Point(10, 10),
77, false, 3, pnl3,
Color.White,
semaphore,
buffer);
p4 = new WaitPanelThread(new Point(250, 10),
77, false, 4, pnl4,
Color.White,
semaphore,
buffer);
p5 = new WaitPanelThread(new Point(10, 250),
77, false, 1, pnl5,
Color.White,
semaphore,
buffer);
semThread = new Thread(new ThreadStart(semaphore.Start));
semThread1 = new Thread(new ThreadStart(semaphore1.Start));
buffThread = new Thread(new ThreadStart(buffer.Start));
buffThread1 = new Thread(new ThreadStart(buffer1.Start));
thread1 = new Thread(new ThreadStart(p1.Start));
thread2 = new Thread(new ThreadStart(p2.Start));
thread3 = new Thread(new ThreadStart(p3.Start));
thread4 = new Thread(new ThreadStart(p4.Start));
thread5 = new Thread(new ThreadStart(p5.Start));
this.Closing += new CancelEventHandler(this.Form1_Closing);
semThread.Start();
semThread1.Start();
buffThread.Start();
buffThread1.Start();
thread1.Start();
thread2.Start();
thread3.Start();
thread4.Start();
thread5.Start();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
private void InitializeComponent()
{
this.Text = "Circuit movements";
this.Size = new System.Drawing.Size(900, 700);
this.BackColor = Color.LightGray;
this.pnl1 = new Panel();
this.pnl1.Location = new Point(100, 100);
this.pnl1.Size = new Size(260, 30);
this.pnl1.BackColor = Color.White;
this.btn1 = new Button();
this.btn1.Size = new Size(30, 30);
this.btn1.BackColor = Color.Pink;
this.btn1.Location = new System.Drawing.Point(0, 0);
this.pnl2 = new Panel();
this.pnl2.Location = new Point(350, 100);
this.pnl2.Size = new Size(260, 30);
this.pnl2.BackColor = Color.White;
this.pnl3 = new Panel();
this.pnl3.Location = new Point(580, 100);
this.pnl3.Size = new Size(30, 260);
this.pnl3.BackColor = Color.White;
this.pnl4 = new Panel();
this.pnl4.Location = new Point(350, 360);
this.pnl4.Size = new Size(260, 30);
this.pnl4.BackColor = Color.White;
this.pnl5 = new Panel();
this.pnl5.Location = new Point(350, 100);
this.pnl5.Size = new Size(30, 260);
this.pnl5.BackColor = Color.White;
this.Controls.Add(pnl1);
this.Controls.Add(pnl2);
this.Controls.Add(pnl3);
this.Controls.Add(pnl4);
this.Controls.Add(pnl5);
this.pnl1.Controls.Add(btn1);
// Wire Closing event.
this.Closing += new CancelEventHandler(this.Form1_Closing);
}
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 planeColor;
private bool empty = true;
public void Read(ref Color planeColor)
{
lock (this)
{
// Check whether the buffer is empty.
if (empty)
Monitor.Wait(this);
empty = true;
planeColor = this.planeColor;
Monitor.Pulse(this);
}
}
public void Write(Color planeColor)
{
lock (this)
{
// Check whether the buffer is full.
if (!empty)
Monitor.Wait(this);
empty = false;
this.planeColor = planeColor;
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 plane;
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.plane = 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 <= 30; k++)
{
this.zeroPlane();
panel.Invalidate();
lock (this)
{
while (locked)
{
Monitor.Wait(this);
}
}
for (int i = 1; i <= 20; i++)
{
this.movePlane(xDelta, yDelta);
Thread.Sleep(delay);
panel.Invalidate();
}
semaphore.Wait();
buffer.Write(this.colour);
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroPlane()
{
plane.X = origin.X;
plane.Y = origin.Y;
}
private void movePlane(int xDelta, int yDelta)
{
plane.X += xDelta; plane.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
g.FillRectangle(brush, plane.X, plane.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 int dir;
/*
* dir options:
* 1 - north;
* 2 - east;
* 3 - south;
* 4 - west.
*/
private Color colour;
private Point plane;
private int xDelta;
private int yDelta;
private Semaphore semaphore;
private Buffer buffer;
public WaitPanelThread(Point origin,
int delay,
bool westEast,
int dir,
Panel panel,
Color colour,
Semaphore sem,
Buffer buff)
{
this.origin = origin;
this.delay = delay;
this.westEast = westEast;
this.dir = dir;
this.panel = panel;
this.colour = colour;
this.plane = origin;
this.panel.Paint += new PaintEventHandler(this.panel_Paint);
switch (dir)
{
case 1:
this.xDelta = 0;
this.yDelta = -10;
break;
case 2:
this.xDelta = +10;
this.yDelta = 0;
break;
case 3:
this.xDelta = 0;
this.yDelta = +10;
break;
case 4:
this.xDelta = -10;
this.yDelta = 0;
break;
}
this.semaphore = sem;
this.buffer = buff;
}
public void Start()
{
this.colour = Color.White;
for (int k = 1; k <= 40; k++)
{
semaphore.Signal();
this.zeroPlane();
buffer.Read(ref this.colour);
for (int i = 1; i <= 20; i++)
{
panel.Invalidate();
this.movePlane(xDelta, yDelta);
Thread.Sleep(delay);
}
this.colour = Color.White;
panel.Invalidate();
}
this.colour = Color.Gray;
panel.Invalidate();
}
private void zeroPlane()
{
plane.X = origin.X;
plane.Y = origin.Y;
}
private void movePlane(int xDelta, int yDelta)
{
plane.X += xDelta; plane.Y += yDelta;
}
private void panel_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
SolidBrush brush = new SolidBrush(colour);
if (dir == 2 || dir == 4)
{
g.FillRectangle(brush, plane.X, plane.Y, 10, 10);
}
if (dir == 1 || dir == 3)
{
g.FillRectangle(brush, plane.X, plane.Y, 10, 10);
}
brush.Dispose(); // Dispose graphics resources.
g.Dispose(); //
}
}// end class WaitPanelThread
public class Driver
{
public static void Main()//
{
Application.Run(new Form1());
}
}// end class TheOne