Delphi Docwiki解释说,Pulse通知等待队列中的下一个线程,只要调用线程释放对象,它便能够锁定指定的对象。 PulseAll发出信号通知等待队列中的所有线程。

我将此代码使用found在线程队列实现中使用Pulse,并给出上面的定义,认为应该使用PulseAll或以不同的方式询问:何时使用Pulse而不是PulseAll正确? (这里的基本问题是:如何确定“队列中的下一个线程”始终位于需要通知的线程之外,除非在琐碎的情况下总共只有两个线程,否则代码可以安全地进行处理)假设唯一等待的线程是需要被提名/“脉冲化”的线程)?

function TSimpleThreadedQueue.Enqueue(const Item: T; Timeout: LongWord): TWaitResult;
begin
  if Closed then Exit(wrAbandoned);
  if not TMonitor.Enter(FQueue, Timeout) then Exit(wrTimeout);
  try
    if Closed then Exit(wrAbandoned);
    FQueue.Enqueue(Item);
    TMonitor.Pulse(FQueue);
    Result := wrSignaled;
  finally
    TMonitor.Exit(FQueue);
  end;
end;

对于Java语言中相应的同步方法,我发现了以下问题:Java: notify() vs. notifyAll() all over again

更新:上面链接的Java问题有一个有趣的答案,该问题显示即使在仅具有put和get两种方法并使用notify()的生产者/消费者应用程序中也可能发生死锁的情况(与Java的Pulse()相对应) :Java: notify() vs. notifyAll() all over again

答案包含建议

最佳答案

在传统的生产者/消费者队列中,每个消费者线程从队列中取出一项。
当您排队一个项目时,您只需要唤醒一个消费者线程即可。由于任何使用者线程都可以处理任务,因此唤醒哪一个线程都没有关系。因此,对Pulse()而不是PulseAll()的调用就足够了。

关于delphi - TMonitor.Pulse与TMonitor.PulseAll,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5911740/

10-13 01:15