Delphi - terminate all threads (TThread) when closing the application

My application is a tcp / ip server, the main thread of which is created only once and is constantly listened to. When a new client connects, the main thread creates a new thread of type TClientThread . However, there is no list of running client threads, as this can make my application a little complicated ... is there a way to execute the β€œcomplete” method for all threads, even if the thread is busy (in my case, β€œbusy”) means that it waiting for data when the timeout is set to about 30 seconds ... so I still have to kill him without waiting.)? A simple closing application does not seem to start the terminate method on threads, which results in memory leaks reported by FastMM ...

+4
delphi terminate fastmm
source share
3 answers

Memory leaks on shutdown - there is nothing to worry about - the problem of freeing memory before returning control to the operating system is a waste of time and unnecessarily slows down the application. All you really need to do is ensure that all data is saved and all interprocess communication handlers (such as semaphores and mutexes) are correctly released and exited.

To notify customers, the best you can do would be a strategy like this:

  • Add all client processing threads to some list somewhere (with a suitable lock on creation, destruction, and iteration).
  • Make client threads removed from the list after completion and remove the last item from the list to set an event (manual reset event, for example TEvent in SyncObjs) if the server shuts down
  • Imagine a poll (e.g. select or a timeout equivalent) or another type of interrupt (e.g. SO_RCVTIMEO / SO_SNDTIMEO) in what would otherwise be a lengthy locking process, controlling the Terminated property
  • When shutting down, block the list and iterate through it by calling Terminate , and then wait for the event to be signaled; Of course, a listening socket that adds elements to the list must be closed and, as you know, closed before repeating in the list
+15
source share

Looks like this article may help.

What you will see if you click on this link:

Using semaphores in Delphi, part 2: Connection Pool

Posted by: Carey Jensen

Abstract: Semaphores are used to coordinate multiple threads and processes. These semaphores provide multiple threads with simultaneous access to a shared resource. The TFixedConnectionPool class is described in this article.

+2
source share

I am using KillThreadList: TList global. I track it in my thread as:

 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; 

I also test KillThreadList in my processes to allow me to drop them before completion, where it is safe.

I pass the OnTerminate event to the Main thread and remove the ThreadID from the KillList. I use this model extensively and it has not failed me yet.

 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; 

In the above case, I also remove some GUI elements.

Hope this helps. SpringerRider

+2
source share

All Articles