最初に、冗長なリクエストについてお詫び申し上げます。
アクティビティがキューに入れられるまで、それぞれの WaitHandle (AutoResetEvent) で待機する多数のスレッドを備えたインフラストラクチャがあります。次の理由で、そのインフラストラクチャを変更することを考えています。各スレッドは、独自のアクティビティで動作します。(管理する一連のさまざまな活動があります)。
現在のインフラストラクチャの欠点は、スレッド (アクティビティ) 自体の数と同じ数の待機ハンドルがあり、スレッド数が増減し続けることができることです。
現在のロジックは次のとおりです。それぞれが独自の AutoResetEvent とアクティビティに関連付けられたスレッドのセット Thread1-Event1-activity1 Thread2-Event2-activity2
Activity
{
Thread th;
AutoResetEvent ev;
Operation();
}
各スレッドはループを実行し、ループ内で操作を実行します。
以下のような擬似コード。
while(event.Wait())
{
//Execute operation (activity-n)
}
そのため、操作をスレッドのキューに入れるコントローラーはイベントを設定するだけで、スレッドはそのタスクを完了し、アクティビティ n の次の要求を待機するために戻ります。
Activity.event.Set();
使用される WaitHandles の数を減らすために私が考えているインフラストラクチャは、すべてのスレッドで 1 つのセマフォを使用することです。
セマフォ カウントを任意の最大数 100 に設定します。セマフォの初期カウントを 0 に設定します。
Semaphore sem = new Semaphore(0,100);
Thread [] threads = new Threads(100);
これで、セマフォは基本的にすべてのスレッドに対してロックされた状態になります。
すべてのスレッドが以前と同じようにループを実行するようになりました
while(sem.Wait())
{
//deque activity
//perform activity
}
ただし、アクティビティには固定スレッドはありません (アクティビティは、集中化された同時実行キューに入れられます)。アクティビティをキューに入れるコントローラーは、次の操作を実行します。
queue.Enqueue(activity-n);
//To release one of the threads from the waiting threads to execute the activity.
semaphore.Release(1).
セマフォの実装は、複数の WaitHandle アプローチよりも優れていますか? もしそうなら、なぜですか?単一のセマフォ アプローチは競合の増加を意味すると私は感じています。
誰かがこれに光を当てることができれば。それは素晴らしいことだ。
更新: リクエストのキューイングが少し独特なので、BlockingCollection は使用していません。複数の種類のアクティビティ (タイプ 1 から n) があり、タイプ n の 1 つのアクティビティが実行されている場合、同じタイプ (たとえば n) の複数のアクティビティを実行できないという条件があります。そのため、最初はアクティビティ タイプごとに 1 つのスレッドを使用していました。関連する待機ハンドルを 1 に減らそうとしていたので、セマフォ アプローチが適合するかどうかを確認しようとしています。しかし、私の懸念は、セマフォ ルートに行くと、ロックの競合が増えることです。私のシナリオでは、常に 1 つまたは 2 つのスレッドがアクティブになっている可能性があります。つまり、残りのすべてのスレッドが、開いているセマフォ内の 1 つまたは 2 つの開いているスロットをめぐって競合します。