线程同步问题,3个线程并发运行,第4个线程必须运行而其他线程正在等待

时间:2013-03-28 10:58:44

标签: c# multithreading .net-3.5 deadlock thread-synchronization

对不起标题,我找不到更好的解释我的问题......

我很难在我的应用程序中尝试同步不同的线程。对于那些对问题有新面貌的人来说,这可能是一个简单的问题,但是经过数小时的关于死锁的调查后,我的头脑爆炸了,我找不到一种好的,安全的方式来编写我的同步机制:(

基本上,我有一个在多个线程中运行的.Net进程(一个进程中的所有内容,因此不需要IPC)。我有4个帖子:

  • 1个帖子,说它叫做 SpecificThread 。有System.Timers.Timer定期执行一些代码。
  • 3个其他线程,每个线程运行一个定期执行某些代码的服务(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必须在其他人等待时运行。我没有找到SemaphoreAutoResetEvent的方法(他们的用法在我的代码中引入了难以调试的死锁)。我这里的想法已经不多了......也许Interlocked静态方法会有帮助吗?

最后一句话:我的代码必须使用.Net 3.5运行,我不能使用任何TPL或CountdownEvent类......

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

ReaderWriterLockSlim听起来就像是最能帮到你的工具。让每个服务在其循环体内取出读锁定:

while (true)
{
    try
    {
        lockObject.EnterReadLock();

        //Do stuff
    }
    finally
    {
        lockObject.ExitReadLock();
    }
}

然后你的第四个线程可以在想要做它的工作时进入锁。读/写锁定工作的方式是任何数量的读者都可以持有锁,只要没有编写者持有锁,并且一次只能有一个编写者持有锁。这意味着三个工作者中没有一个会阻止其他工作者,但是如果第四个线程正在运行,那么工作人员将会打包,这完全你想要的。