アプリケーションのコンテキストは次のとおりです。
- シングルプロセスマルチスレッドプログラムです
- 自動化された先物取引用に設計されています。先物取引市場では、数百のアクティブな先物契約があります。各コントラクトのマーケット データはティック データと呼ばれ、Future-Exchange から 500 ミリ秒ごとにプッシュされます。各自動先物取引戦略はスレッドとして実行されます。各戦略には、異なる契約のリアルタイムの市場データが必要です。例: 戦略 A は、契約 A1、契約 A2、および契約 A3 の市場データを必要とします。ストラテジー B は、コントラクト A1、コントラクト B1、コントラクト B2 のマーケット データを必要とします。
- このプログラムの 1 つのスレッドは、すべての契約の市場データを受信し、取引後にディスク データベースに保存できるデータ バッファーに保存する市場データ レシーバーとして実行されます。したがって、このスレッドはデータ プロデューサーとしてレビューでき、ストラテジー スレッドはデータ コンシューマーとしてレビューできます。したがって、このシナリオは単一生産者複数消費者の問題です。設計では、すべての戦略スレッドが必要なティック データを効率的に取得できるようにする必要があります。
- 考えられる設計の 1 つは、すべてのコンシューマーが条件変数を待機し、共有ロックを取得しようとすることです。新しいティックが来ると、シングル プロデューサーは排他ロックを取得し、このティック データをデータ バッファーに保存しようとします。次に、条件変数ですべての消費者に通知します。コンシューマーは通知を受けると、データ バッファーを取得して、必要なコントラクト データが更新されているかどうかを確認します (タイムスタンプを比較します)。いいえの場合、再び条件変数を待ちます。しかし、この効率の低い設計では、新しいティック データが来るたびに、すべてのコンシューマーがデータ バッファーを起動して取得することになります (取得の過程で、データが必要かどうかに関係なく、時間がかかる場合があります)。
- 改善された設計は次のとおりです。 グローバル変数を定義して、新しく来るティック データを格納します。新しいティック データが来ると、プロデューサーはグローバル変数を更新し、ティック データをデータ バッファーに格納してから、すべてのコンシューマーに通知します。コンシューマーは目を覚まし、グローバル変数をチェックして、ティックデータが必要かどうかを確認します (データバッファー全体を取得する必要はありません)。しかし問題は、いくつかの競合状態が存在することです。コンシューマが共有ロックを取得する前に、別の新しいティック データが来て、プロデューサが先にロックを取得し、グローバル変数を更新する場合があります。そのため、消費者は 1 つのティック データを見逃すことになります。より良いデザインはありますか?(例えば、unix ドメイン ソケットを使用してブロードキャストしますか? unix ドメイン ソケットをマルチスレッド間で適用できるかどうかはわかりません。そうであれば、共有メモリを比較した場合の効率はどうですか?)