私は取引ソフトウェアを書いています。私のシステムは、処理する必要がある「順次アイテム」(1、2、3...) を生成します (私のアプリケーションでは、各アイテムは実行の順序であり、ID は内部注文 ID と呼ばれます)。
アイテムを生成できるスレッドが多数あります (多くの戦略) が、各アイテムが 1 回だけ生成されることが保証されています。
必要なプロセッサー (注文執行者) は 1 つだけです。
- 新しいアイテムが利用可能になるたびに、実行のために送信します(注文します)
- コールバックで結果を受け取り、「アイテム結果」を更新します(証券取引所からの応答を取得します)
各生産者は
- 実行する項目の「順次パック」を送信します (たとえば、「1234,1235,1236,1237」を送信します)。
- すべてのアイテムの結果が利用可能になるまでブロックします。すべてのアイテムの結果が利用可能になったとき - プロセス
ご了承ください:
- アイテムは別のスレッドから並行して送信できます
- 最小限の遅延と最小限の「ロック」が必要です
- C++ への移植が容易なコードがあると便利です
- いつでも、かなり「限られた」数の「ライブ」IDを持っています。たとえば、ライブIDの「1と10000」を同時に持つことはできません。新しい ID が作成されるたびに、処理してクリーンアップする必要があるためです。したがって、私は常に互いに近いIDのセットを持っています(たとえば、〜9900-10000)。したがって、実装に cycle-array を使用することはおそらく理にかなっています
何か提案できる場合は、提案してください。以下に奇妙な実装を追加しますが、読む必要はありません。
これは私の問題の実装です:
private Dictionary<uint, AutoResetEvent> transactionsEvents = new Dictionary<uint, AutoResetEvent>();
private Dictionary<uint, TransactionResult> transactionsResults = new Dictionary<uint, TransactionResult> ();
public void IssueOrders(List<OrderAction> actions)
{
int count = actions.Count;
if (count == 0)
{
return;
}
uint finishUserId = (uint) apiTransactions.counter.Next(count);
uint startUserId = finishUserId + 1 - (uint) count;
AutoResetEvent[] events = new AutoResetEvent[count];
for (int i = 0; i < count; i++)
{
var action = actions[i];
uint userId = startUserId + (uint) i;
action.UserId = userId;
var e = new AutoResetEvent(false);
events[i] = e;
transactionsEvents[userId] = e;
}
for (int i = 0; i < count; i++)
{
var action = actions[i];
apiTransactions.ScheduleOrderAction(action);
}
WaitHandle.WaitAll(events);
// now all answers are available, need to apply information
foreach (var action in actions)
{
UpdateActionWithResult(action, transactionsResults[action.UserId]);
transactionsResults.Remove(action.UserId);
}
}
ScheduleOrderAction
BlockingCollection にアイテムを追加します。プロセッサーは BlockingCollection からアイテムを実行し、結果を transactionsResults に入れ、対応するイベントを発生させます。
私の実装には多くの問題があります。
- さまざまなスレッドから辞書にアクセス (および変更) します。たとえば、あるスレッドが
transactionResults
別のスレッド (プロセッサ) からアイテムを削除すると、それにアイテムが追加される場合があります。 - 私は ConcurentDictionaries に切り替えたくありません。Dictionary でさえも (速度の点で) 私にとっては高すぎるからです。