タイトルで申し訳ありませんが、私の問題を説明するのにこれ以上のものが見つかりませんでした...
アプリケーションで異なるスレッドを同期するのに苦労しています。これはおそらく、この問題に新しい見方を持っている人にとっては簡単な問題ですが、デッドロックについて何時間も調査した後、私の頭は爆発しており、同期メカニズムを作成する適切で安全な方法を見つけることができません:(
基本的に、複数のスレッドで実行される .Net プロセスがあります (すべてが 1 つのプロセスで実行されるため、IPC は必要ありません)。私は4つのスレッドを持っています:
- 1 つのスレッド、それがSpecificThreadと呼ばれているとします。
System.Timers.Timer
定期的にコードを実行する があります。 - 他に 3 つのスレッドがあり、それぞれが定期的にコードを実行するサービスを実行しています (
while (true)
loop +Thread.Sleep(few ms)
)。
3 つのサービスはすべて同時に実行する必要があります。それらの同時実行がスレッドセーフであることを保証します。4 番目のスレッドであるSpecificThreadは、そのコードを定期的に実行する必要がありますが、他の 3 つのサービスの実行をブロックする必要があります。
基本的に、コードを定期的に実行するSpecificThreadがあります。SpecificThreadがそのコードを定期的に実行する場合、他のサービスがタスクを完了するまで待機する必要があります。他の 3 つのサービスがすべてタスクを完了したら、他の 3 つのサービスがブロックされている間、そのSpecificCodeを実行する必要があります。そのSpecificCodeが実行されると、他の 3 つのサービスがコードを再度実行できます。
SynchronizationContext
4 つのスレッドすべてで共有されるオブジェクトの共有インスタンスがあります。これを使用してスレッドを同期できます。
public class SynchronizationContext
{
public void StartService1()
{
...
}
public void StopService1()
{
...
}
...
public void StartSpecificCode()
{
// Some sync here that wait until all 3 services completed their
// respective tasks
}
public void NotifySpecificCodeCompleted()
{
// Some sync here that allows services 1 to 3 to execute again
}
}
3 つのサービスの実行メカニズムは次のようになります。
// Only exits the loop when stopping the whole .Net process
while (myService.IsRunning)
{
try
{
this.synchronizationContext.StartService1();
// Do some job
}
finally
{
this.synchronizationContext.EndService1();
// Avoids too much CPU usage for nothing in the loop
Thread.Sleep(50);
}
}
SpecificThread実行メカニズム:
// System.Timers.Timer that is instantiated on process start
if (this.timer != null)
{
this.timer.Stop();
}
try
{
// Must blocks until computation is possible
this.synchronizationContext.StartSpecificCode();
// Some job here that must execute while other 3
// services are waiting
}
finally
{
// Notify computation is done
this.synchronizationContext.NotifySpecificCodeCompleted();
// Starts timer again
if (this.timer != null)
{
this.timer.Start();
}
}
SpecificThread
他の人が待っている間だけ実行する必要があるため、クリティカルセクションの使用方法がわかりません。Semaphore
私は、 norを使用する方法を見つけられませんでしたAutoResetEvent
(それらを使用すると、コードでデバッグが困難なデッドロックが発生しました)。ここでアイデアが不足しています...Interlocked
静的メソッドが役立つでしょうか?
最後の言葉: 私のコードは .Net 3.5 で実行する必要があります。TPL もCountdownEvent
クラスも使用できません...
どんな助けでも大歓迎です!