c# - Monitor.Wait() 和 Monitor.Pulse() 的线程问题

标签 c# asp.net multithreading

我在 ASP.NET 中有一个生产者-消费者场景。我设计了一个Producer 类,一个Consumer 类和一个用于保存共享对象并负责Producer 和Consumer 之间通信的类,我们称它为Mediator。因为我在启动时 fork 执行路径(在父对象中)并且一个线程会调用 Producer.Start() 而另一个线程会调用 Consumer.Start(),我需要将 Mediator 的引用传递给 ProducerConsumer(通过 Constructor)。 Mediator 是一个智能类,它将优化许多事情,例如它的内部队列的长度,但现在将其视为循环阻塞队列。 Producer 会将新对象排队Mediator,直到队列满为止,然后Producer 会阻塞。 Consumer dequeues 来自 Mediator 的对象,直到队列中没有任何对象。对于线程之间的信号,我在 Mediator 类中实现了两个方法:Wait()Pulse()。代码是这样的:

Class Mediator
{
  private object _locker = new object();

  public void Wait()
  {
    lock(_locker)
      Monitor.Wait(_locker);
  }

  public void Pulse()
  {
    lock(_locker)
      Monitor.Pulse(_locker);
  }
}

// This way threads are signaling:

Class Consumer
{
  object x;
  if (Mediator.TryDequeue(out x))
    // Do something
  else
    Mediator.Wait();
}

在 Mediator 内部,每次入队出队时,我都会使用this.Pulse(),这样等待的线程就会收到信号并继续它们的工作.

但我遇到了死锁,因为我从未使用过这种设计来发送信号线程,所以我不确定是设计有问题还是我在其他地方做错了什么?

谢谢

最佳答案

这里没有太多代码可以继续,但我最好的猜测是你有一个 live-lock问题。如果 Mediator.PulseMediator.Wait 之前调用,那么即使队列中有内容,信号也会丢失。这是实现阻塞队列的标准模式。

public class BlockingQueue<T>
{
  private Queue<T> m_Queue = new Queue<T>();

  public void Enqueue(T item)
  {
    lock (m_Queue)
    {
      m_Queue.Enqueue(item);
      Monitor.Pulse(m_Queue);
    }
  }

  public T Dequeue()
  {
    lock (m_Queue)
    {
      while (m_Queue.Count == 0) 
      {
        Monitor.Wait(m_Queue);
      }
      return m_Queue.Dequeue();
    }
  }
}

请注意 Monitor.Wait 是如何仅在队列为空时调用的。还要注意它是如何在 while 循环中被调用的。这是因为 Wait 没有 Enter 的优先级,因此进入 Dequeue 的新线程可能会占用最后一项,即使调用Wait 准备返回。如果没有循环,线程可能会尝试从空队列中删除一个项目。

关于c# - Monitor.Wait() 和 Monitor.Pulse() 的线程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3956127/

相关文章:

c# - 如何在多个 Linq IQueryable 上执行 sql Union

c# - 如何在服务器端获取 window.location.hash?

C# 类关键字变量

c# - Xamarin表单选择器设置了所选项目

asp.net - IIS Url 重写模块重写 Url 的页面上的 Response.Redirect

java - 在 Tomcat 下启动线程

c++ - _beginthreadex 的参数类型错误

iphone - 在 Core Data 的后台线程上使用获取请求

c# - 如何添加 "MS Visual Studio 20xx Tools for Office Runtime"?

asp.net - 发布 : Could not find a part of the path …\obj\DEV\AspnetCompileMerge\Source\bin\roslyn\csc. exe'