1

我正在尝试找到一种方法来同步具有以下条件的多个线程:

  • 有两种类型的线程:
    1. 单个“循环”线程执行无限循环以进行循环计算
    2. 主线程未启动多个短命线程
  • 循环线程在每个循环/循环迭代之间有一个睡眠持续时间
  • 允许其他线程在循环线程的循环间睡眠期间执行:
    • 任何其他试图在活动周期中执行的线程都应该被阻止
    • 循环线程将一直等待,直到所有其他已经在执行的线程完成

这是我正在考虑做的一个基本示例:

// Somewhere in the code:
ManualResetEvent manualResetEvent = new ManualResetEvent(true); // Allows external call
CountdownEvent countdownEvent = new CountdownEvent(1); // Can't AddCount a CountdownEvent with CurrentCount = 0

void ExternallyCalled()
{
    manualResetEvent.WaitOne(); // Wait until CyclicCalculations is having its beauty sleep

    countdownEvent.AddCount(); // Notify CyclicCalculations that it should wait for this method call to finish before starting the next cycle

    Thread.Sleep(1000); // TODO: Replace with actual method logic

    countdownEvent.Signal(); // Notify CyclicCalculations that this call is finished
}

void CyclicCalculations()
{
    while (!stopCyclicCalculations)
    {
        manualResetEvent.Reset(); // Block all incoming calls to ExternallyCalled from this point forward

        countdownEvent.Signal(); // Dirty workaround for the issue with AddCount and CurrentCount = 0
        countdownEvent.Wait(); // Wait until all of the already executing calls to ExternallyCalled are finished

        countdownEvent.Reset(); // Reset the CountdownEvent for next cycle.

        Thread.Sleep(2000); // TODO: Replace with actual method logic

        manualResetEvent.Set(); // Unblock all threads executing ExternallyCalled

        Thread.Sleep(1000); // Inter-cycles delay
    }
}

显然,这是行不通的。不能保证ExternallyCalledmanualResetEvent.WaitOne();countdownEvent.AddCount();线程被CountdownEvent.

我想不出一个简单的方法来做我所追求的,经过长时间的搜索,我发现的几乎所有东西都与生产者/消费者同步有关,我不能在这里应用。

编辑:解决方案

根据接受的答案,这是如何做我想做的事情的要点:

// Somewhere in the code:
ReaderWriterLockSlim readerWriterLockSlim = new ReaderWriterLockSlim();

void ExternallyCalled()
{
    readerWriterLockSlim.EnterReadLock();

    Thread.Sleep(1000); // TODO: Replace with actual method logic

    readerWriterLockSlim.ExitReadLock();
}

void CyclicCalculations()
{
    while (!stopCyclicCalculations)
    {
        readerWriterLockSlim.EnterWriteLock();

        Thread.Sleep(2000); // TODO: Replace with actual method logic

        readerWriterLockSlim.ExitWriteLock();

        Thread.Sleep(1000); // Inter-cycles delay
    }
}
4

1 回答 1

4

看起来你需要一个ReaderWriterLockSlim。您的循环线程是“作者”,其他线程是“读者”。

于 2013-11-07T15:55:48.787 回答