Multithreading 等待事件,但至少等待指定的时间

Multithreading 等待事件,但至少等待指定的时间,multithreading,delphi,events,delphi-10.4-sydney,Multithreading,Delphi,Events,Delphi 10.4 Sydney,目前,我提出了以下代码: 先决条件: CONST MinTime = 1000; // ms // VAR ObjHandle : THandle := CreateEvent(NIL,TRUE,FALSE,'Event'); VAR T : LongWord; VAR Signalled : BOOLEAN; 代码: 这段代码的目的是等待外部发出信号的事件(来自另一个线程),但最多每秒响应一次。这是实现此功能的正确方法,还是有更优化的(CPU资源方面的)方法?您的代码与事件有关。有两个选项:

目前,我提出了以下代码:

先决条件:

CONST MinTime = 1000; // ms //
VAR ObjHandle : THandle := CreateEvent(NIL,TRUE,FALSE,'Event');
VAR T : LongWord;
VAR Signalled : BOOLEAN;
代码:


这段代码的目的是等待外部发出信号的事件(来自另一个线程),但最多每秒响应一次。这是实现此功能的正确方法,还是有更优化的(CPU资源方面的)方法?

您的代码与事件有关。有两个选项:自动重置和手动重置事件。使用auto reset event(自动重置事件),当
WaitForSingleObject
返回时,如果事件if auto reset(自动重置)将被重置,您将释放该事件


您可以使用手动重置事件并管理您自己(更复杂),或者,一旦您捕获了事件并且之前处理的时间太短,请使用简单的
睡眠
等待丢失的时间。

您的代码与事件有关。有两个选项:自动重置和手动重置事件。使用auto reset event(自动重置事件),当
WaitForSingleObject
返回时,如果事件if auto reset(自动重置)将被重置,您将释放该事件


您可以使用手动重置事件并管理您自己(更复杂),或者,一旦您抓取了事件并且之前处理的时间太短,请使用简单的
睡眠
来等待丢失的时间。

您可以使用两个对象来等待。一个是事件。另一种是一次性设置为所需的睡眠间隔。然后与
bWaitAll=TRUE
一起使用,等待两个对象发出信号,无需循环。

您可以使用两个对象等待。一个是事件。另一种是一次性设置为所需的睡眠间隔。然后与
bWaitAll=TRUE
一起使用,等待两个对象都发出信号,不需要循环。

您不需要事件

只要使用一个变量,如果它应该是线程安全的,就可以使用一个临界部分

比如:

var signal: boolean;

  signal := false;
  sleep(minTime);
  if signal then
  begin
    // do something
    signal := false;
  end;

用任何条件替换
信号
布尔值,如
如果somelist.count>0,则

不需要事件

只要使用一个变量,如果它应该是线程安全的,就可以使用一个临界部分

比如:

var signal: boolean;

  signal := false;
  sleep(minTime);
  if signal then
  begin
    // do something
    signal := false;
  end;

用任何条件替换
信号
布尔值,比如
如果somelist.count>0,那么
..

我也会犯这个错误(
=
而不是
:=
在新的内联变量声明中)。当然,这是因为我们几十年来一直以这种方式声明常量。@AndreasRejbrand:啊,是的。这部分代码不是直接从我的源代码复制/粘贴的,而是为了澄清先决条件而添加的。我会将其更新为:=(顺便问一下:如何使文本变为“灰色”?我知道下划线变为斜体,但变为灰色?)灰色的单间距文本用于内联代码。您可以使用严重的重音来完成此操作:
normal`code`normal
变为“normal
code
normal”。听起来您需要的只是一个循环,每秒钟检查一次事件是否发生。@SolomonSlow:是的,但我希望使用尽可能少的CPU时间,那么这个循环应该如何实现呢?我也犯了这个错误(
=
而不是新的内联变量声明中的
:=
)。当然,这是因为我们几十年来一直以这种方式声明常量。@AndreasRejbrand:啊,是的。这部分代码不是直接从我的源代码复制/粘贴的,而是为了澄清先决条件而添加的。我会将其更新为:=(顺便问一下:如何使文本变为“灰色”?我知道下划线变为斜体,但变为灰色?)灰色的单间距文本用于内联代码。您可以使用严重的重音来完成此操作:
normal`code`normal
变为“normal
code
normal”。听起来您需要的只是一个循环,每秒钟检查一次事件是否发生。@SolomonSlow:是的,但我希望使用尽可能少的CPU时间,那么这个循环应该如何实现呢?实际上,我的代码是手动重置的。但这没关系,因为my
Signaled
在第一个
WAIT_OBJECT_0
返回时设置,并在循环的其余部分保持设置。稍后,我只需检查
signaled
变量,查看事件是否在我循环的第二次循环中触发。自动重置也可以工作,但可能会导致(近)2秒的循环,因为它可以在0.99秒后设置
信号
变量,然后重置事件,然后再等待一秒钟,以便再次设置。睡眠
不是CPU密集型吗?我一开始使用的是
Sleep
,但我想我在某个地方读到过,应该用事件来表示类似的东西(这是我从另一个线程添加到的队列,需要偶尔清空,但我不想在没有添加任何内容的情况下花费太多CPU时间)。
Sleep
不使用任何CPU,您可以使用任务管理器非常轻松地进行验证。但是人们通常不想使用
sleep
睡眠线程,因为它是不可中止的。@HeartWare
sleep
几乎不使用CPU<代码>睡眠
在给定的持续时间内将线程置于挂起模式。这就是为什么事件睡眠(0)有很多意义:它只是停止分配给调用
Sleep
的线程的时间片。因此,一个
Sleep(1000)
然后是
IF List.Count>0,那么
也会一样好(这就是我开始时使用的)?实际上,我的代码是手动重置的。但这没关系,因为my
Signaled
在第一个
WAIT_OBJECT_0
返回时设置,并在循环的其余部分保持设置。稍后,我只需检查
signaled
变量,查看事件是否在我循环的第二次循环中触发。自动重置也可以工作,但可能会导致(近)2秒的循环,因为它可以在0.99秒后设置
信号
变量,然后重置事件,然后再等待一秒钟,以便再次设置。这不是
睡眠
C吗