0

我有几个线程之间共享的资源和以下使用模式:

  • 线程 1 不断使用受保护的资源。

  • 线程 2..N 需要在很短的时间内不频繁地与受保护的资源进行交互。

我希望线程 1 在其工作周期中的特定时间不断地持有保护资源的锁,让其他线程等待轮到它们。如果没有其他线程碰巧在等待,它应该立即重新获取锁并继续它的工作。

我想一种方法是这样的:

lock (resource)
{
    while (!stop)
    {
        resource.DoWorkIteration();

        // give other threads a chance
        Monitor.Exit(resource);
        Thread.Sleep(0); 
        Monitor.Enter(resource);
    }
}

但是 Sleep(0) 将让步给任何准备运行的线程,而不仅仅是等待这个特定资源的线程。

有没有更好的方法来避免不必要的屈服?

4

1 回答 1

2

这是一个一般性建议,但您应该协调对资源的访问,而不是竞争资源。原因是锁定、解锁和上下文切换的开销不可忽略,而且它总是存在死锁的危险。释放和重新获取锁也不是免费的,所以你最好避免它。

在您的情况下,我建议线程 2..N 需要完成的资源实际上由线程 1 完成。为此,请使用存储在队列中的回调(最好是非阻塞操作的回调)。当队列为空时,线程 1 做自己的事情,否则它会从队列中弹出一个回调并执行它。如果您需要结果,请使用请求线程等待的事件。也许您还可以利用 .Net 使用的现有系统将来自非 UI 线程的调用委托给 UI 元素。

于 2013-09-28T07:24:38.880 回答