我目前正在为我的 asm 模拟器创建一个管道。我要用多线程来做到这一点。目前我有四个线程,分别对应于 Fetch、Decode、Execute 和 Write Back。我对如何编写正确的管道感到困惑。这是我的一些代码:
private void Fetch()
{
while(_continue)
{
fetchEvent.WaitOne();
if (!_continue) break;
lock (irLock)
{
try
{
// Do stuff to fetch instruction...
catch (IndexOutOfRangeException e) { Err = "Segmentation Fault at Line " + _pc.ToString(); }
catch (Exception e) { Err = e.Message + "Line " + _pc.ToString(); }
_pc++;
GiveTurnTo(2); // used these 2 lines to handle mutual exclusion
WaitTurn(1);
}
}
}
private void Decode()
{
while (_continue)
{
decodeEvent.WaitOne();
if (!_continue) break;
lock (irLock)
{
WaitTurn(2);
Console.WriteLine("decode works");
GiveTurnTo(1);
}
}
}
private void Execute()
{
while (_continue)
{
exeEvent.WaitOne();
if (!_continue) break;
lock (irLock)
{
//WaitTurn(3);
Console.WriteLine("Am I, execute, getting a turn?");
// GiveTurnTo(4);
}
}
}
private void WriteBack()
{
while (_continue)
{
wbEvent.WaitOne();
if (!_continue) break;
lock (irLock)
{
Console.WriteLine("Am I, Write Back, getting a turn?");
//GiveTurnTo(1);
// WaitTurn(4);
}
}
}
}
我使用此方法通过单击按钮运行循环:
public void nextInstruction()
{
fetchEvent.Set();
decodeEvent.Set();
exeEvent.Set();
wbEvent.Set();
}
I was thinking of changing nextInstruction() to this:
public void nextInstruction()
{
fetchEvent.Set();
}
每个按钮单击将始终以 Fetch 开头。在那之后,我想也许我可以在 Fetch 方法中放置一个 set 事件来调用循环中的下一部分(解码)并对以下方法执行相同的操作。我最终会得到这样的结果:
private void Fetch()
{
while(_continue)
{
// Do stuff....
decodeEvent.Set();
}
}
private void Decode()
{
while (_continue)
{
// Do stuff...
exeEvent.Set();
}
}
private void Execute()
{
while (_continue)
{
// Do stuff...
wbEvent.Set();
}
}
private void WriteBack()
{
while (_continue)
{
// Do stuff...
}
}
与其把这些设定的事件公开,我认为它们应该被某种逻辑激活,但我不知道是什么样的逻辑。也许它们可以通过单击按钮来激活。这将允许我控制指令何时在循环中传递。从理论上讲,我认为这可以给我一个管道的结构。任何人都可以对此提供任何意见吗?这可以通过自动重置事件来完成吗?
如果您查看我提供的第一段代码,您会发现我尝试使用锁,但这使得它一次只能运行一个线程。我想让它遵循等的格式Fetch0, {Decode0, Fetch1}, {Execute0, Decode1, Fetch3},...
。在这种情况下,锁是必需品吗?