gpt4 book ai didi

multithreading - "Pausing"具有属性的线程

转载 作者:行者123 更新时间:2023-12-03 15:08:04 24 4
gpt4 key购买 nike

我有一个 TThread 对象,希望能够通过程序主窗体上的按钮启动/停止线程。我一直在寻找实现这一目标的方法,到目前为止我有以下想法:

  1. 当用户单击“停止”时终止并释放线程,并在单击“开始”时创建一个新线程。
  2. 使用 sleep 来延迟线程(我不想这样做)
  3. 有一个 bool 值属性来确定线程是否暂停。仅当此 bool 值为 false 时,执行中的代码才会发生。

我倾向于#3。从主窗体中设置 TThread 对象的 bool 属性是否是线程安全的?

我应该选择以下哪个选项或更好的选择?这是我第一次使用线程,因此非常感谢您的帮助。

最佳答案

1.Terminate and Free the thread when the user clicks stop and create a new one when they click start.

如果开销很小,这当然是一个选择。

3.Have a property that is a boolean to determine if the thread is paused or not. The code in the Execute will only happen if this boolean is false.

您可以这样做,但您必须定期检查该 bool 值,如果设置,则进入等待循环,直到它被清除或线程收到终止信号。

Would setting a boolean property on the TThread object from the main form be threadsafe?

它与调用 TThread.Terminate() 一样是线程安全的,只需设置 bool 值 TThread.Termminate 属性即可。

Which of these options, or any better alternative, should I go with?

我使用选项 #4 - 使用信号事件而不是 bool 值。例如:

type
TMyThread = class(TThread)
private
FRunEvent, FTermEvent: TEvent;
FWaitEvents: THandleObjectArray;
procedure CheckPause;
protected
procedure Execute; override;
procedure TerminatedSet; override;
public
constructor Create; reintroduce;
destructor Destroy; override;
procedure Pause;
procedure Unpause;
end;

constructor TMyThread.Create;
begin
inherited Create(False);

FRunEvent := TEvent.Create(nil, True, True, '');
FTermEvent := TEvent.Create(nil, True, False, '');

SetLength(FWaitEvents, 2);
FWaitEvents[0] := FRunEvent;
FWaitEvents[1] := FTermEvent;
end;

destructor TMyThread.Destroy;
begin
FRunEvent.Free;
FTermEvent.Free;
inherited;
end;

procedure TMyThread.Execute;
begin
while not Terminated do
begin
// do some work...
CheckPause;
// do some more work...
CheckPause;
// do some more work...
CheckPause;
//...
end;
end;

procedure TMyThread.TerminatedSet;
begin
FTermEvent.SetEvent;
end;

procedure TMyThread.CheckPause;
var
SignaledEvent: THandleObject;
begin
while not Terminated do
begin
case TEvent.WaitForMultiple(FWaitEvents, INFINITE, False, SignaledEvent) of
wrSignaled: begin
if SignaledEvent = FRunEvent then Exit;
Break;
end;
wrIOCompletion: begin
// retry
end;
wrError: begin
RaiseLastOSError;
end;
end;
SysUtils.Abort;
end;

procedure TMyThread.Pause;
begin
FRunEvent.ResetEvent;
end;

procedure TMyThread.Unpause;
begin
FRunEvent.SetEvent;
end;

关于multithreading - "Pausing"具有属性的线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38516091/

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