Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A proper way of destroying a TThread object

This question may seem trivial, but I hope you won't ignore it.
Before destroying a TThread object it is usually necessary to wait until the thread that called the TThread.Execute() method finishes, for only then can we be sure that, for instance, the objects destroyed inside the class's destructor are no longer accessed. Therefore it is necessary to call Terminate to set the Terminated flag that the thread has to check to know whether to exit or not, and then call the WaitFor() method.

Because the thread may be suspended, I think it is good to resume it before calling WaitFor, as otherwise the calling thread would be deadlocked. And because the thread can be suspended multiple times, it should be resumed the same number of times, right?

while Suspended do
  Resume;

If the thread was created suspended, we do not have to worry that the TThread.Execute() method will be called when we resume the thread only to terminate it - it won't (please correct me if I'm wrong).

What I've stated suggests using the following lines of code for each TThread object being freed:

MyThread.Terminate;
while MyThread.Suspended do
  MyThread.Resume;
MyThread.WaitFor;
MyThread.Free;

Unfortunately, when we destroy our application that has created multiple threads, writing such a piece of code for each TThread object being destroyed unnecessarily makes the code very long and maybe even opaque.

Therefore I came to a conclusion that all these could be put inside an overriden destructor of the TThread class thanks to which it would be enough to call MyThread.Free (or MyThread.Terminate if MyThread.FreeOnTerminate is set) without caring about whether the destroyed object is a TThread object or not:

destructor TMyThread.Destroy;
begin
  //if FreeOnTerminate, the calling thread cannot wait for itself
  if GetCurrentThreadId <> ThreadId then
  begin
    Terminate;
    while Suspended do
      Resume;
    WaitFor;
  end;

  {free all objects created in this class}

  inherited Destroy;
end;

Forgive me asking such a basic question. I would like, however, to get to know your opinions about this way - I hope an universal way - of destroying TThread objects. I ask this questions for I learned from my workmates' codes that they usually used the first example of code to destroy such objects, but they never used to check whether the threads being waited for were not suspended which I considered a bit dangerous if the threads might be suspended somewhere in the code. Therefore I tried to find a universal way of destroying the objects of this class that would make the code clearer and safer. I hope I didn't make it worse - what do you think?

Thanks for your suggestions in advance.

like image 704
Mariusz Schimke Avatar asked Jul 06 '09 22:07

Mariusz Schimke


People also ask

How do you destroy a thread?

Modern ways to suspend/stop a thread are by using a boolean flag and Thread. interrupt() method. Using a boolean flag: We can define a boolean variable which is used for stopping/killing threads say 'exit'. Whenever we want to stop a thread, the 'exit' variable will be set to true.

Which method is used to terminate a thread?

Whenever we want to stop a thread from running state by calling stop() method of Thread class in Java. This method stops the execution of a running thread and removes it from the waiting threads pool and garbage collected. A thread will also move to the dead state automatically when it reaches the end of its method.

How do you kill a thread in C++?

The C++11 does not have direct method to terminate the threads. The std::future<void> can be used to the thread, and it should exit when value in future is available. If we want to send a signal to the thread, but does not send the actual value, we can pass void type object.

How do you use thread abortion?

If Abort is called on a managed thread while it is executing unmanaged code, a ThreadAbortException is not thrown until the thread returns to managed code. If two calls to Abort come at the same time, it is possible for one call to set the state information and the other call to execute the Abort .


1 Answers

Much of what your suggesting is already performed in the TThread.Destroy destructor, and invoking TMyThread.free will do just what your suggesting. To cleanup any objects owned by the thread class, you can perform that in the OnTerminate event, which will get invoked as part of the thread shutdown logic.

like image 127
skamradt Avatar answered Sep 21 '22 05:09

skamradt