对不起标题,我找不到更好的解释我的问题......
我很难在我的应用程序中尝试同步不同的线程。对于那些对问题有新面貌的人来说,这可能是一个简单的问题,但是经过数小时的关于死锁的调查后,我的头脑爆炸了,我找不到一种好的,安全的方式来编写我的同步机制:(
基本上,我有一个在多个线程中运行的.Net进程(一个进程中的所有内容,因此不需要IPC)。我有4个帖子:
System.Timers.Timer
定期执行一些代码。while (true)
loop + Thread.Sleep(few ms)
)。所有3项服务必须同时运行。我保证他们的并发执行是线程安全的。 第四个线程 SpecificThread 必须定期执行其代码,但必须阻止执行其他3个服务。
所以基本上我有 SpecificThread 定期执行代码。当 SpecificThread 想要定期执行其代码时,它必须等待其他服务完成其任务。当所有其他3个服务完成其任务时,它必须执行其 SpecificCode ,而其他3个服务被阻止。当执行 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
或AutoResetEvent
的方法(他们的用法在我的代码中引入了难以调试的死锁)。我这里的想法已经不多了......也许Interlocked
静态方法会有帮助吗?
最后一句话:我的代码必须使用.Net 3.5运行,我不能使用任何TPL或CountdownEvent
类......
感谢任何帮助!
答案 0 :(得分:1)
ReaderWriterLockSlim
听起来就像是最能帮到你的工具。让每个服务在其循环体内取出读锁定:
while (true)
{
try
{
lockObject.EnterReadLock();
//Do stuff
}
finally
{
lockObject.ExitReadLock();
}
}
然后你的第四个线程可以在想要做它的工作时进入写锁。读/写锁定工作的方式是任何数量的读者都可以持有锁,只要没有编写者持有锁,并且一次只能有一个编写者持有锁。这意味着三个工作者中没有一个会阻止其他工作者,但是如果第四个线程正在运行,那么工作人员将会打包,这完全你想要的。