德尔福 - 终止所有的收盘应用程序线程(TThread类)(delphi - terminate a

2019-06-27 04:12发布

我的应用程序是一个TCP / IP服务器,与主线程创建一次,和听力所有的时间。 当新的客户端连接,主线程创建的新线程TClientThread类型。 然而,有没有正在运行的客户端线程的列表,因为这将让我的应用程序有点复杂......有没有什么办法来执行“终止”方法上的所有线程,即使线程是忙(在我的情况“忙”意味着它在等待数据,超时设置为30秒......所以我无论如何都要杀了它,无需等待。)? 简单的收盘应用似乎并没有对线程,从而与FastMM报告的内存泄漏最终运行“终止”的方法...

Answer 1:

在关机时内存泄漏是完全不用担心 - 将控制返回给操作系统之前释放内存的麻烦是在浪费时间和无谓地减慢应用程序退出。 你真正需要做的是确保所有数据已保存,所有进程间句柄(如信号量和互斥)正确释放,并退出了。

通知客户,你能做的最好的将是一个策略有点像这样:

  • 添加所有客户端处理线程一些地方名单(有合适的​​锁定上的创造,毁灭和迭代)
  • 让客户端线程终止时列表中删除自己,可以从列表中删除最后一个项目设置的事件(手动重置事件,如TEvent在SyncObjs)如果服务器关闭
  • 介绍轮询(如select或等效采用超时)或其他种类的中断(例如SO_RCVTIMEO / SO_SNDTIMEO)在什么否则将长期运行阻止程序,监督物业终止
  • 在关机,锁定列表,并遍历它,称Terminate ,然后等待要通知的事件; 当然,这会增加项目列表中的监听套接字应该关闭和已知被关闭通过列表迭代前


Answer 2:

听起来像这篇文章可以帮助

你会看到什么,如果你点击这个链接:

在Delphi中使用信号量,第2部分:连接池

通过:卡里詹森

摘要:信号被用来协调多个线程和进程。 该信号量提供多个线程以对共享资源的同时访问是通过本文中描述的TFixedConnectionPool类高亮显示。



Answer 3:

我使用的是KillThreadList:从TList全球。 我监视它在我的主题为:

while (Not Terminated) do
begin
  inc(Inker);
  if (WaitForSingleObject(FTick, finterval) = WAIT_TIMEOUT) then
  Begin
    if Inker >= 10 then
    Begin
      ProcessTables;
      Inker := 0;
      sleep(1000);
    End;
    if KillThreadList.Contains(ThreadID) = True then Terminate;
  End;
end;

我在过程中也测试了KillThreadList让我完成,在安全的时候才选择了出来。

我通过OnTerminate事件到主线程,并从那里KillList删除线程ID。 我大量使用这种模式,也没有让我失望呢。

procedure TfrmProcessQualcommLocations.OnTerminateThread;
var
  ThreadID : Cardinal;
  i : integer;
  aStatusBar :TStatFrame;
begin
  ThreadID := (Sender as Tthread).ThreadID;
  for i := 0 to StatusBarList.Count -1  do
  Begin
    if StatusBarList.Items[i].ThreadID = ThreadID then
    Begin
      aStatusBar := StatusBarList.Items[i];
      KillThreadList.Extract(ThreadID);
      StatusBarList.Extract(aStatusBar);
      aStatusBar.Free;
      break;
    End;
  End;

  self.Refresh;
end;

在上面的例子中,我也删除了一些GUI的东西。

希望帮助。 SpringerRider



文章来源: delphi - terminate all the threads (TThread) on closing application