3

我正在用 Java/Swing 编写一台旧计算机的模拟器,我想我已经确定了我遇到的设计问题。尽管这个应用程序很奇特,但我怀疑有人会找到解决这个问题的“模式”。

我应该补充一点,我仍然是 OOP、GUI 和设计模式的初学者。

该机器有一个 GUI 线程 (Console) - 带有按钮和开关,以及一个模型线程 (CPU),控制台与模型线程 (CPU) 通信以使控制台事件改变 CPU 的状态。当然,控制台是来自 AWT 事件队列的事件驱动。控制台通过在 CPU 接收的优先阻塞队列上排队消息来与 CPU 通信。因此,CPU 也被构造为事件循环。到现在为止还挺好。

问题是,当您在控制台上按下 START 时,您希望 CPU 开始执行其内存中的任何程序。它仍然需要响应来自控制台的开关抛出和按钮推动(例如 STOP),但它主要需要坐在那里并通过其指令获取-解码-执行循环进行旋转。

甚至这在一段时间内也没有问题:我有一个名为Cycle()的方法,它将执行当前指令的一个特定“周期”,然后返回,立即重新调度以执行下一个周期。我将 Cycle() 的调用放在 CPU 的运行循环中,并在每个循环后轮询消息队列。如果 CPU 停止,运行循环将简单地等待消息队列。

现在:我正在执行 I/O 指令,例如读卡。其中一个周期有必要向相关外围设备发送数据请求(其本身实现为在单独线程上运行的 GUI/模型),然后等待数据到达。这完全打破了 CPU 是一个简单的事件循环的概念,它接收消息并对其进行操作,而不会导致进程阻塞。这个新的循环阻塞。如果操作员没有将卡片组加载到读卡器中,它可能会阻塞很长时间。

我曾考虑将指令 fetch-decode-execute 循环分解为一个单独的“工作”线程,但我认为这不太合适,因为工作线程(据我所知)旨在异步运行以完成,并且运行时不要继续与其父线程交互。(事实上​​,我想不出为什么“工作线程”应该终止。)此外,当一个循环需要访问由于控制台按键而可以同时修改的数据时,目前不需要同步。

那么,我如何设法将“事件驱动”处理与需要在继续之前显式等待消息的传统批处理相结合呢?

4

2 回答 2

2

在典型的真实系统中,每个单独的设备实际上将并行运行(即,在其自己的线程上),但在您的模拟中将其建模为单独的线程当然是有意义的。您需要确保在实际 CPU 中实现某种类似于中断系统的功能,以在工作人员完成其工作时处理同步(例如,用于捕获“I/O 中断”等的新优先级队列) )。阅读 Maurice Bach的The Design of the UNIX Operating System可能会对您有所帮助。它详细介绍了 UNIX 如何与底层硬件交互,并且可能是您项目的一个很好的资源。

于 2011-07-26T01:14:21.303 回答
2

工作线程(据我了解)旨在异步运行以完成,并且在运行时不继续与其父线程交互。

一个常见的实现,SwingWorker,没有特定的时间限制,它可以通过该方法在事件调度线程的生命周期内不断地在事件调度线程上传递结果。publish()我看到的唯一潜在问题是相应的process()方法可能会收到合并的结果。作为参考,这里有一个例子

或者,让您的 CPU 型号使用计时器来驱动 fetch-decode-execute 循环。javax.swing.Timer很方便,因为它的动作事件处理程序在事件调度线程上执行。您必须使用本文中描述的技术来同步对任何共享数据的访问。

最后,您可能会查看这个答案,其中提到了 Java 中的 6502 仿真。

于 2011-07-26T08:23:30.620 回答