TMonitor.Pulse vs TMonitor.PulseAll [英] TMonitor.Pulse vs TMonitor.PulseAll

查看:369
本文介绍了TMonitor.Pulse vs TMonitor.PulseAll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Delphi Docwiki解释说, Pulse 通知下一个线程等待队列,一旦调用线程释放对象,它就能够锁定指定的对象。 PulseAll 表示等待队列中的所有线程。

The Delphi Docwiki explains that Pulse notifies the next thread in the waiting queue that it will be able to lock the specified object as soon as the calling thread releases the object. PulseAll signals all threads in the waiting queue.

发现这个在线程队列实现中使用Pulse的代码,并给出上面的定义,认为应该使用PulseAll或者以不同的方式询问:使用Pulse而不是PulseAll是正确的? (其中基本的问题是:我如何确定'队列中的下一个线程'是线程需要通知的线程,除了在总共只有两个线程的简单情况下,或代码可以安全地假设唯一的等待线程是需要被清除/'脉冲'的线程)?

I found this code which uses Pulse in a threaded queue implementation, and given the definition above, think that PulseAll should be used - or asked in a different way: when is it correct to use Pulse instead of PulseAll? (Where the basic question is: how can I be sure that the 'next thread in the queue' is alyways the thread who needs to be notified, except in the trivial cases when there are only two threads in total, or the code can safely assume that the only waiting thread is the thread who needs to be nofified/'pulsed')?

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()与notifyAll()一遍又一遍

For the corresponding synchronization methods in the Java language I found this question: Java: notify() vs. notifyAll() all over again

更新:上面链接的Java问题有一个有趣的答案,显示即使在仅有两种方法的生产者/消费者应用程序中,死锁也可能发生,并且使用notify()(Pulse()的Java对应物): Java:notify()与notifyAll()全部结束

Update: the Java question linked above has one interesting answer which shows how a deadlock can occur even in a producer/consumer application which has only two methods, put and get, and which uses notify() (the Java counterpart of Pulse()): Java: notify() vs. notifyAll() all over again

答案包含建议


如果您不确定要使用哪个,那么
使用 notifyAll


推荐答案

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

In a traditional producer/consumer queue, each consumer thread takes one item off the queue. When you enqueue a single item you only need to wake up a single consumer thread. Since any of the consumer threads can handle the task, it does not matter which one is woken up, so long as one is. Thus a call to Pulse() rather than PulseAll() suffices.

这篇关于TMonitor.Pulse vs TMonitor.PulseAll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆