2016-10-31 6 views
1

私は、何らかの種類のプロデューサー/消費者シナリオについていくつかの概念的アドバイスを得たいと考えています。複数の消費者が同じ価値を持っている

私は通常、定期的にいくつかの整数値または倍精度値を作成する "プロデューサー"スレッドがあるとしましょうが、その間に任意の遅延があるかもしれません。

ここでは、値が到着するとすぐに、この値を使って何かを並行して実行しなければならないいくつかの「コンシューマ」スレッドがあります。

「コンシューマ」スレッドのそれぞれは、そのタスクを実行するために別の時間が必要な場合があります。 「消費者」が準備ができたら、それは次の生産価値を待つべきです。

ただし、以前の値でタスクを終了するには時間がかかりすぎると、消費者は期限切れの値があればすぐに続行する必要があります。私はキューを必要としません、消費者が働いている間に何人かが到着すれば、値はスキップされるかもしれません。したがって、新しい価値がある場合、そして消費者が次の価値を消費する準備ができている場合には最新の価値があることは、もっとも重要です。

"消費者"ごとに1つのAutoResetEvent/ManualResetEventを設定する以外に有効な方法はありますか?

特定のソリューションはUnity3Dで動作するはずですので、Mono2が必要です。

編集:私は概念的なアドバイスに興味があるので、いくつかのソースコードを考え出すのは難しいです。私は次のことが少し問題を説明することを願っています。

int data = 0; 

producer = new Timer(20, OnTimer); 
consumer1 = new Consumer(OnConsume1); 
consumer2 = new Consumer(OnConsume2); 

OnTimer() 
{ 
     data = data + 20; 
     TriggerConsumers(); 
} 

OnConsume1() 
{ 
     while (running) 
     { 
       WaitForData(); 
       // do something with data 
       Thread.Sleep(10); 
     } 
} 

OnConsume2() 
{ 
     while (running) 
     { 
       WaitForData(); 
       // do something with data 
       Thread.Sleep(30); 
     } 
} 

20msごとに新しい値を作成するプロデューサーがあります。次に、値を待って何かを行う消費者が2人(後であるかもしれません)です。一方の消費者は10ms、もう一方の消費者は30msかかる。 プロデューサー/消費者が同時に起動する場合、これは、次のタイムラインにつながるはず:あなたが利用できる単一の値以上にしたい場合は、最大深さと、スタック/キューをお勧めしますよう

 
20  data = 20 => OnConsume1, OnConsume2 run with data = 20 
30  OnConsume1 will wait for data, OnConsume2 is "working" 
40  data = 40 => OnConsume1 run with data = 40, OnConsume2 still "working" 
50  OnConsume1 will wait, OnConsume2 will run with data = 40 
60  data = 60 => OnConsume1 run with data = 60, OnConsume2 is "working" 
70  OnConsume1 will wait, OnConsume2 still "working" 
80  data = 80 => OnConsume1 => data = 80, OnConsume2 should also run with 80 (neglecting the race that it might work with 60) 
+0

いくつかのコード(擬似コードなど)がないと、少なくとも私にとっては何が問題なのかはっきりしません。 – Evk

+0

たとえば、次のデータをプロデューサ:2から受信した場合3.最初に3を処理し、他にデータがない場合は2を処理する必要がありますか?この場合、2をスキップする必要がありますか?あなたの消費者の1人が他の人より2倍速く働くので、2人と3人の両方を処理できますが、もう1人は3人だけ処理します。 – oldovets

+0

疑似コードでそれを実証しようとしました。ユースケースはゲーム要素のタイムライン情報であり、すべての消費者は「現在の」時間を知る必要があります。しかし、私は他者をブロックするので、消費者を介して同期的にループしたくありません。したがって、あなたの例では、2は3で上書きされた場合は処理されません。一度に1つの値しかありません。しかし、それが処理され、新しいものがなければ、消費者は次のものを待つべきです。 – JeffRSon

答えて

0

が鳴ります。または、nullのような単一の値。

public int? value; 

OnConsume1() 
{ 
     while (running) 
     { 
       int myValue; 
       if(value != null) // or value.HasValue 
       { 
        myValue = value.Value; // or (int)value 
        value = null; // let other consumers know the value is being processed 
        // do something with data 
       } 
       Thread.Sleep(10); 
     } 
} 

一度に値(複数可)を修正するだけつのスレッドを維持するためにC#のlock機能を使用したいと思います。

スレッドセーフコンテナを使用する場合はcheck out theseです。

関連する問題