Indy10线程池BUG:Idyarn线程使用Synchronize导致TerminateAllYarns挂死的解决办法

本文介绍了一个线程池程序中出现的死锁问题及其解决方案。通过在主线程中加入Application.ProcessMessages;来处理子线程的Synchronize操作,避免了因无限循环导致的界面挂死现象。

写了个线程池程序。用TerminateAllYarns来结束线程,每次老是界面挂死在此段代码。
起初以为是代码同步或互斥问题,查了半天没找到。于是跟踪原代码进去,发现原来是这段代码导致了死循环:

------------------IdScheduler.pas--------------

procedure TIdScheduler.TerminateAllYarns;
var
i: Integer;
begin
while True do begin
// Must unlock each time to allow yarns that are temrinating to remove themselves from the list
with FActiveYarns.LockList do try
if Count = 0 then begin
Break;
end;
for i := 0 to Count - 1 do begin
TerminateYarn(TIdYarn(Items[i]));
end;
finally FActiveYarns.UnlockList; end;
//TODO: Put terminate timeout check back
Sleep(500); // Wait a bit before looping to prevent thrashing
end;
end;

一旦idyarn调用对应线程使用了Synchronize,则必须有一段程序插到主线程去运行才能继续。结果主线程执行到此TerminateAllYarns时,就开始没完没了的置stop标志了。于是主线程就挂死在此了。

改进办法是:
在for i := 0 to Count - 1 do begin前加入Application.ProcessMessages;令主线程喘口气运行子线程的Synchronize代码,这样就不会在此没完没了的stop死循环了。

不过这样又得注意一个问题,就是一旦Application.ProcessMessages允许事件冒泡,那么可能重复触发TerminateAllYarns导致在FActiveYarns.LockList时死锁,因此设置判断避免TerminateAllYarns重复触发

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值