我的应用程序是一个tcp / ip服务器,主线程仅创建一次&一直在听。当新客户端连接时,主线程创建TClientThread
类型的新线程。但是没有运行客户端线程的列表,因为这会使我的应用程序有点复杂...有没有办法在所有线程上执行“terminate”方法,即使线程忙(在我的情况下“忙”)意味着它正在等待数据,超时设置大约是30秒......所以无论如何我都要杀掉它,而不是等待。)?
简单的关闭应用程序似乎不会在线程上运行“terminate”方法,最终会导致FastMM报告的内存泄漏......
答案 0 :(得分:16)
关机时的内存泄漏无需担心 - 在将控制权返回给操作系统之前解决内存泄漏的麻烦是浪费时间并且不必要地减慢应用程序退出的速度。您真正需要做的就是确保已保存所有数据,并正确释放所有进程间句柄(如信号量和互斥量),然后退出。
对于通知客户,您可以做的最好的策略是这样的策略:
TEvent
)select
或等效的超时)或其他类型的中断(例如SO_RCVTIMEO / SO_SNDTIMEO),否则将是长时间运行的阻塞例程,监控已终止的属性Terminate
,然后等待事件发出信号;当然,在遍历列表之前,应该关闭将列表添加到列表中的侦听套接字并将其关闭答案 1 :(得分:2)
Sounds like this article may help
点击该链接后会看到什么:
在Delphi中使用信号量,第2部分: 连接池
作者:Cary Jensen
摘要:信号量用于 协调多个线程和 流程。信号量提供 多个线程同时进行 访问共享资源是 突出显示 TFixedConnectionPool类描述 在这篇文章中。
答案 2 :(得分:2)
我使用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