德尔福-终止所有的线(TThread)在封闭程序
题
我应用程序是一个tcp/ip的服务器,与主要线创建了唯一一次听所有的时间。当新的客户连接,主要线创造新的线 TClientThread
类型。但是没有名单的运行客户线,因为这将使我的程序有点复杂...是否有任何方法来执行"终止"的方法上的所有螺纹,即使该线是忙(在我的情况"忙"意味着它的等待数据,其中超时设定为大约30秒...所以我必须杀了它,无论如何,没有等待。)?简单的关闭程序似乎是不运行"终止"的方法上线,其结束与存储器泄漏报告FastMM...
解决方案
存储器泄漏关机都没什么好担心的-要的麻烦,释放内存在返回之前控制的操作系统是一个时间的浪费和不必要地减慢了应用程序退出。你真的需要做的是确保所有数据已被储存,以及所有的进程处理(例如信号和互斥)正确地释放和退出走。
通知客户,最好可以做将是一项战略,有些是这样的:
- 添加所有的客户处理线的一些列表中的某处(有适当的锁定在建立、破坏和迭代的)
- 让客户线删除了自己从该名单一旦终止,并有最后的项目从名单中删除设置一个事件(手工重置事件,例如
TEvent
在SyncObjs)如果服务器正在关闭 - 介绍询(例如
select
或者相当于超时)或其他类型的中断(例如SO_RCVTIMEO/SO_SNDTIMEO)在,否则什么是长期阻止程序,监测终止的财产 - 在关闭,锁定列表和迭代过它,叫
Terminate
, ,然后等待事件的报告;当然,听座其中增加了项目清单应该被关闭以及已知前关闭循环,通过列表
其他提示
点击该链接后会看到什么:
在Delphi中使用信号量,第2部分: 连接池
作者:Cary Jensen
摘要:信号量用于 协调多个线程和 流程。信号量提供 多个线程同时进行 访问共享资源是 突出显示 TFixedConnectionPool类描述 在这篇文章中。
我使用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事件传递给Main线程并从那里删除了KillList中的ThreadID。我广泛使用这个模型,但它还没有让我失望。
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
不隶属于 StackOverflow