gpt4 book ai didi

multithreading - 线程终止(再次…)

转载 作者:行者123 更新时间:2023-12-03 19:07:59 29 4
gpt4 key购买 nike

当我通过将终止标志设置为true来停止线程'srch_slave_thread'时,(srch_slave_thread.terminate)释放线程的线程停止在析构函数的'inherited'行中,为什么?挂着的是WaitFor吗?如果我在析构函数中注释掉“继承”,则线程停止并释放自身。

取出“继承”并调试代码后:为什么线程在调用析构函数后跳入DoTerminate方法?

谢谢你。

Tsrch_slave_thread = class(TThread)   
private
FSW: TStopWatch;
protected
procedure Execute; override;
public
SimpleEvent: TSimpleEvent;
procedure DoTerminate; override;
...
constructor Create;
destructor Destroy; override;
end;

创建一个事件对象。在构造函数中>>
constructor Tsrch_slave_thread.create;
begin
inherited create(true);
Fsw := TStopWatch.Create;
SimpleEvent := TSimpleEvent.Create;
end;

调用析构函数后跳到此处? >>
procedure Tsrch_slave_thread.DoTerminate;
begin
inherited;
self.simpleEvent.SetEvent;
end;

线程在析构函数中的继承处挂起>>
destructor Tsrch_slave_thread.destroy;
begin
self.SimpleEvent.free;
inherited;
end;

在这里创建线程>>
function TMaster.th_slvsearch_start: integer; 
begin
if not Assigned( Fslave_search_thread ) then begin
Fslave_search_thread := TFslave_search_thread.create;
...
end
else begin
...
exit;
end;
with Fslave_search_thread do
begin
master := self;
master_HWND := self.fMsgHandlerHWND;
FreeOnTerminate := false;
OnTerminate := slvsrch_termination;
start;
end;
end;

停止线程从这里开始>>
procedure TMaster.th_slvsearch_stop;
begin
Fslave_search_thread.Terminate;
end;

线程执行>>
procedure Tsrch_slave_thread.Execute;
var
text_orig: string;
activesearch: integer;
begin
FSW.Start;
while not terminated do begin
activesearch := master.CMD_LISTCNT;
//stopper refresh
synchronize(procedure begin
with self.master do
Fmasternode.text := FmasterDat.MstrName + ' (' + floattostr(Fsw.ElapsedMilliseconds / 1000) + 'sec - Searching)';
end);
if (SimpleEvent.WaitFor(2000) <> wrTimeOut) or (activesearch <> 1) then break;
end;
FSW.Stop;
end;

OnTerminate事件处理程序>>
procedure TMaster.slvsrch_termination(Sender: TObject);
begin
if Assigned( Fslave_search_thread ) then
begin
self.FLastSearchTime := Fslave_search_thread.FSW.ElapsedMilliseconds / 1000;
Fslave_search_thread.Free;
Fslave_search_thread := nil;
self.Factive_slv_search := 0;
end;
...
end;

最佳答案

您正在通过Free事件处理程序在线程对象上调用OnTerminate。仅此而已是一个错误,因为您无法在引发事件的同时释放对象,因为当事件返回时,您现在正在已破坏的对象中执行代码。

但这不是您的直接问题。由于对WaitFor中的TThread.Destroy的调用,您已使线程陷入僵局。线程无法完成,因为它正在等待自身。线程上的调用堆栈如下所示:

同步(CallOnTerminate)
终结
线程处理

因此线程正在等待主线程完成CallOnTerminate的执行。在主线程上,OnTerminate处理程序内部是对Free的调用。进而导致调用WaitFor。因此,主线程正在等待线程完成。那是您的经典僵局。线程A等待线程B,线程B等待线程A。

这个故事的寓意是:永远不要在Free事件处理程序内的线程上调用OnTerminate

解决方案可能是将FreeOnTerminate设置为True,并在OnTerminate处理程序中将Fslave_search_thread设置为nil

关于multithreading - 线程终止(再次…),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22349048/

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