私は Java/Swing で古いコンピューターのエミュレーターを書いていますが、私が抱えている設計上の問題を特定したと思います。このアプリケーションは独特ですが、誰かがこの問題の「パターン」を見つけるのではないかと思います。
私はまだ OOP、GUI、およびデザイン パターンの初心者であることを付け加えておきます。
マシンには、押しボタンとスイッチを備えた GUI スレッド (コンソール) と、コンソールが通信してコンソール イベントによって CPU の状態を変更するモデル スレッド (CPU) があります。もちろん、コンソールは AWT イベント キューからのイベント ドリブンです。コンソールは、CPU が受信するプライオリティ ブロッキング キューにメッセージをキューイングすることによって、CPU と通信します。そのため、CPU もイベントループとして構造化されています。ここまでは順調ですね。
問題は、コンソールで START を押すと、CPU がメモリに持っているプログラムの実行を開始することです。コンソールからのスイッチ スローとボタン押し (STOP など) に応答する必要がありますが、主にそこに座って、命令フェッチ - デコード - 実行ループをスピンする必要があります。
それもしばらくの間は問題になりませんでした。Cycle()というメソッドがありました。このメソッドは、現在の命令の特定の「サイクル」を実行してから戻り、次のサイクルを実行するためにすぐに再ディスパッチされます。CPU の実行ループ内に Cycle() の呼び出しを配置し、サイクルごとにメッセージ キューをポーリングしました。CPU が停止した場合、実行ループは単にメッセージ キューで待機します。
現在: I/O 命令を実装しています。たとえば、カードの読み取りなどです。サイクルの 1 つで、問題の周辺機器 (それ自体は別のスレッドで実行される GUI/モデルとして実装されている) にデータの要求を送信し、データが到着するのを待つ必要があります。これにより、CPU が単純なイベント ループであるという概念全体が完全に破られ、メッセージを受信し、プロセスでブロックを発生させることなくそれらに作用します。この新しいサイクルはブロックされます。また、オペレーターがカード デッキをリーダーにロードしていない場合、長時間ブロックされる可能性があります。
命令 fetch-decode-execute ループを別の「ワーカー」スレッドに分割することを考えましたが、ワーカー スレッド (私が理解しているように) は完了するまで非同期で実行することを目的としているため、適切ではないと思います。実行中に親スレッドと対話し続けないでください。(実際、「ワーカー スレッド」が終了しなければならない理由が思いつきません。 ) また、現在、コンソール キーを押した結果として同時に変更できるデータにサイクルがアクセスする必要がある場合、同期は必要ありません。
では、先に進む前にメッセージを明示的に待機する必要がある従来のバッチプロセスと「イベント駆動型」の処理を融合するにはどうすればよいでしょうか?