2011-12-19 5 views
3

と共有リソースとアクションIは、以下のタスクがありますスレッド同期:異なるリソース番号需要

を等価リソース(例えば入力スロット)をプールし、このプールを用いて実行されるアクションのセットがあります。

各アクションは別のスレッドで実行されます。

各アクションでは、使用可能な入力スロットの数が異なります。すべてのアクションのスレッドが同時に

実行されている入力スロットの必要数は

スロットを自由に使用することがときにアクションが実行され

は、私は、次のタスクのセマフォのようなものを使用したいですアクションは、それがセマフォ負の初期値を設定するか、それが負になるまで値をデクリメントすることは不可能ですので、私は定期的にセマフォを使用することはできません

を終了したときに自由に設定されている

だから、私はそれを解決することができますどのように任意の提案

を「リソース値がNに達するまで待つ」のようになめらかにし、機能WaitMultiple(int型N)と「セマフォ」を、必要ですか? 私は、スレッドブロック/リリースを好む、私はセマフォがここに有用であることがわからないアクティブループ

+0

私はC#セマフォーで作業しませんでした。私は答えられません。しかし、ディスパッチのための別のスレッドでループを使用するとコストが高すぎるという結論にどのように到達したかに興味がありますか? – Fdr

+0

アクティブループでは、私は(for;)if(free_slots> N)breakのようなsmthを意味しました。あなたはどういう意味ですか? – HtonS

+0

+1:これは素晴らしい質問です。 –

答えて

3

を買う余裕はありません。

私はあなたがスレッドプールとCS/mutexで保護されたセクションのいくつかのコードでこれを行うことができると思います。アクションをコレクション(list/queue/stack、ディスパッチアルゴリズムに最適なもの)に置き、スロットカウントを初期化します。次に、アクションが完了してスロットが解放されるたびに、CSを入力し、現在のスロットカウントが与えられた場合に実行するアクションを決定します。これらのアクションをスレッドプールに提出し、スロットカウントを適切に減らしてCSを終了します。本当に重要ではありません -

「スロット数」は単純な整数またはいくつかの複雑なクラスのコレクション数である可能性があります。

たび空きスロット数の増加は、スレッドプールに派遣するアクションについての決定をしなければなりません。スロットリリースによって複数のアクションを実行する可能性があるように思われるので、何らかのアルゴリズムが必要です。スロットの要件が最も高いアクションを実行しますか?

別のディスパッチャスレッドは必要ありませんし、CPUループもありません。使用可能なスロットのためにいくつかのシンクロオブジェクトを待つことによってスロットターゲットを蓄積しようとするスレッドに基づく解決策は、デッドロックの危険性があることを恐れています - 多くのスレッドが部分的なスロット数で詰まり、また、あなたはアルゴリズムを微調整して、例えばスロット要求が高い状態で飢えている行動を防ぐことはできません。

+0

+1:私はこのアイデアが好きです。私は、いくつかのスロットを必要とするアクションによって多くのスロットが飢えてしまうことを必要とするアクションを防ぐために、何らかの対策を想定しています。しかし、ええ、これは本当にスケーラブルな戦略のようです。 –

+1

スロット要件と待機時間に基づいて、いくつかの「優先度」によってアクションのリストを順序付けることが考えられます。返されたスロットは、リストの最初の項目に最初に適用されます。最終的には、大きなスロットカウントを必要とするアクションは、年齢を待っていたのでリストの先頭に終わるので、スロットがあるまでそこに座るだろう。 –

+0

ありがとう、マーティン!あなたの答えは助けになりました! – HtonS

1

ネガティブカウントの可能性のある独自の高速セマフォを実装できます。たとえば、MySemaphoreクラスを次のように設定します。

public class MySemaphore 
{ 
    private int size; // number of occupied resources 
    private readonly int capacity; // total capacity 

    public MySemaphore(int size, int capacity) 
    { 
     this.size = size; 
     this.capacity = capacity; 
    } 

    public void Lock(int count) // acquire "count" resources 
    { 
     lock(this) 
     { 
      while(capacity - size < count) 
      { 
       Monitor.Wait(this); 
      } 
      size += count; 
     } 
    }   

    public void Unlock(int count) // release "count" resources 
    { 
     lock(this) 
     { 
      size -= count; 
      Monitor.PulseAll(this); 
     } 
    } 
} 
+0

ありがとう、チューダー。あなたの答えを前のものと組み合わせると思います。それは答えとして2つの投稿をチェックすることはできません – HtonS