首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Monitor.Pulse失去了信号?

Monitor.Pulse失去了信号?
EN

Stack Overflow用户
提问于 2012-08-02 21:37:57
回答 1查看 207关注 0票数 2

我有这样的生产者/消费者代码:

MAIN:

代码语言:javascript
复制
static void Main()
{
    using(PCQueue q = new PCQueue(2))
    {
        for(int i = 0; i < 10; i++)
        {
            int itemNumber = i; // To avoid the captured variable trap
            q.EnqueueItem(() = > {
                Thread.Sleep(1000); // Simulate time-consuming work
                Console.Write(" Task" + itemNumber);
            });
        }
        Console.WriteLine("Enqueued 10 items");
        Console.WriteLine("Waiting for items to complete...");
    }

}

类:

代码语言:javascript
复制
   public class PCQueue: IDisposable
  {
      readonly object _locker = new object();
      Thread[] _workers;
      Queue < Action > _itemQ = new Queue < Action > ();
      public PCQueue(int workerCount)
      {
          _workers = new Thread[workerCount];
          // Create and start a separate thread for each worker
          for(int i = 0; i < workerCount; i++)
          (_workers[i] = new Thread(Consume)).Start();
      }
      public void Dispose()
      {
          // Enqueue one null item per worker to make each exit.
          foreach(Thread worker in _workers) EnqueueItem(null);
      }
      public void EnqueueItem(Action item)
      {
          lock(_locker)
          {
              _itemQ.Enqueue(item); // We must pulse because we're
              Monitor.Pulse(_locker); // changing a blocking condition.
          }
      }
      void Consume()
      {
          while(true) // Keep consuming until
          { // told otherwise.
              Action item;
              lock(_locker)
              {
                  while(_itemQ.Count == 0) Monitor.Wait(_locker);
                  item = _itemQ.Dequeue();
              }
              if(item == null) return; // This signals our exit.
              item(); // Execute item.
          }
      }
  }

问题:

假设执行item();需要很长时间。

代码语言:javascript
复制
1) we enqueue a new work and pulse. ( 1 consumer is busy now)
2) we enqueue a new work and pulse. ( second consumer is busy now)
3) we enqueue a new work and pulse. 

那现在呢?两个线程都很忙!

I know 表示脉冲将丢失(或不丢失?)

唯一的解决方案是将其更改为AutoResetEvent吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-08-02 21:54:39

现在呢?两个线程都很忙!

我知道脉搏会丢失(或者不会?)

是的,当(所有)线程都忙于执行Item()调用时,Pulse将丢失。

但这不是问题,您在每次入队()之后都会产生脉冲,基本上,只有当queue.Count从0变为1时才需要脉冲。您还有更多的脉冲。

但是,当你试图优化脉冲的数量时,你可能会遇到麻烦。Wait/Pulse是无状态的,这一事实确实意味着您应该谨慎使用它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11778635

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档