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

写了个线程池程序。用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重复触发

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值