gpt4 book ai didi

multithreading - 当不需要时在 Delphi 中自动挂起线程并安全地恢复

转载 作者:行者123 更新时间:2023-12-03 14:57:43 26 4
gpt4 key购买 nike

这个问题涉及 Delphi 和 XE 特别反对挂起和恢复。我读过其他帖子,到目前为止还没有找到类似的用法,所以我将继续要求讨论。

我想知道是否有更好的方法在不需要线程时暂停线程?

我们有一个已经使用多年的 Delphi 类,它基本上是一个与线程进程关联的 FIFO 队列。队列在主线程上接受数据对象,如果线程被挂起,它将恢复它。

作为线程执行过程的一部分,对象将从队列中弹出并在线程上进行处理。通常这是为了进行数据库查找。

在进程结束时,对象的属性被更新并标记为可用于主线程或传递到另一个队列。执行过程的最后一步(实际上是第一步)是检查队列中是否还有更多项目。如果有则继续,否则则自行挂起。

它们的关键是,唯一的挂起操作是在执行循环完成时执行的,并且在正常操作期间唯一的恢复是在将新项目放入队列时调用的。异常是当队列类被终止时。

恢复函数看起来像这样。

process TthrdQueue.MyResume();
begin
if Suspended then begin
Sleep(1); //Allow thread to suspend if it is in the process of suspending
Resume();
end;
end;

执行看起来与此类似

process TthrdQueue.Execute();
var
Obj : TMyObject;
begin
inherited;
FreeOnTerminate := true;
while not terminated do begin
if not Queue.Empty then begin
Obj := Pop();
MyProcess(Obj); //Do work
Obj.Ready := true;
end
else
Suspend(); // No more Work
end; //Queue clean up in Destructor
end;

TthrdQueue Push 例程在堆栈中添加另一个对象后调用 MyResume。 MyResume 仅在线程挂起时调用 Resume。

关闭时,我们将终止设置为 true,并在挂起时调用 MyResume。

最佳答案

我推荐以下 TthrdQueue 实现:

type
TthrdQueue = class(TThread)
private
FEvent: THandle;
protected
procedure Execute; override;
public
procedure MyResume;
end;

implementation

procedure TthrdQueue.MyResume;
begin
SetEvent(FEvent);
end;

procedure TthrdQueue.Execute;
begin
FEvent:= CreateEvent(nil,
False, // auto reset
False, // initial state = not signaled
nil);
FreeOnTerminate := true;
try
while not Terminated do begin
if not Queue.Empty then begin
Obj := Pop();
MyProcess(Obj); //Do work
Obj.Ready := true;
end
else
WaitForSingleObject(FEvent, INFINITE); // No more Work
end;
finally
CloseHandle(FEvent);
end;
end;

关于multithreading - 当不需要时在 Delphi 中自动挂起线程并安全地恢复,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4401171/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com