覚えておいてください: 「動作するまで」デバッグする場合のように、マルチスレッド アプリケーションを正常にデバッグする方法はありません。
デッドロックが発生しないこと、およびすべてのデータ アクセスが必要な場所でシリアル化されていることを何らかの形で証明する方法が必要です。これを行うのは非常に難しく、経験豊富な開発者でさえ特定のケースを見逃す可能性があります。
したがって、設計によって特定の特性 (たとえば、デッドロックからの自由) が保証されるように、マルチスレッド アプリケーションを設計することが非常に重要です。前の文のどこにもデバッグについて言及されていないことに注意してください。エラーハンティングではなく、設計によって機能する必要があります。
次の 2 つの主要な問題があります。
データ構造へのアクセスのシリアル化。
デッドロック。
以下で説明するイベント ドリブンまたは CSP アプローチは、#1 を自動的に処理します。デッドロックの問題は些細なことではなく、今でも活発な研究テーマです。つまり、デッドロックがないことを証明する方法 (およびそのための設計も!) です。
デッドロックからの自由など、特定のプロパティの確認と正式な証明をより簡単にする設計の一例は、逐次プロセスの通信 (CSP)です。
CSP アプローチは、ほとんどのアプリケーション開発フレームワークで利用でき、シェアード ナッシング イベント ドリブン システムとして実装できます。主な機能は次のとおりです。
スレッドは、相互にイベント (メッセージ) を送信することによって通信します。
データ構造はスレッド間で直接共有されることはなく、代わりにイベントがデータを所有します。
イベントがポストされたときにイベント キューに順次アクセスするために、唯一の同期が行われます。
これだけで、高レベルの抽象化がイベント パッシングを使用してデッドロックを起こしやすい抽象化を再実装していない限り、デッドロックからの自由が保証されます。たとえば、哲学者の食事の行き詰まりの問題は、イベントの受け渡しでも取得できますが、イベント (メッセージ) を介してリソースに関する情報を明示的に渡すようになりました。したがって、問題は少なくとも明確になり、あなたはそれについて考えざるを得なくなります。問題は、いわば隠蔽されていません。
デッドロック/ライブロックが発生しないことを証明する正式な手法は、 CSP を実装するイベント パッシング プロダクション コードに適用する方が簡単です。イベントを受け入れるコードは、状態のセットだけでなく、各状態の受け入れられたイベントのセットの抽出を可能にするランタイム イントロスペクションを提供できます (内部的にはステート マシンになります)。多くの場合、この情報は、デッドロックの可能性がないことを証明するのに十分な場合もあれば、別の方法で対処できるデッドロック シナリオの小さなセットを列挙するのに十分な場合もあります。結局のところ、CSP 形式主義は通常、ソフトウェアの完全なセマンティクスをキャプチャすることはできないため、セマンティクス自体を使用して、デッドロックが発生しないこと、または別の方法で処理されることをさらに示すことができます。