tags:

views:

91

answers:

3

Dear Experts:

Yesterday experts advised using "while not terminated do begin..." in thread execute function to check thread terminated property and exit the thread gracefully from within. We just tested code, but it still can not terminate thread. But this thread can be terminated practically and immediately by calling TerminateThread function externally. There is something defective in execute function or in that large while loop within execute function? Or are there special requirements when using while not terminated loop?

By the way, what are difference between endthread, exitthread,and terminatethread? how to use them? which is comparatively better?

Thank you so much again for your help.

+6  A: 

If while not Terminated do doesn't terminate the thread soon enough, then the work done in each iteration is too much (that is, the loop condition not Terminated is checked too seldom), or you have "accidently" put a lot of code after this loop.

Of course, if you have a thread that runs a loop over and over again, until terminated, then you should do while not Terminated do. Typically one iteration is completed in short time (in the order of 1 to 10000 iterations per second?), so the loop condition is checked often (between 1 and 10000 times per second). But if your thread doesn't consist of such a loop, then, of course, putting the entire Execute body inside a while not Terminated do will not help you.

Good

procedure TMyThread.Execute;
begin
  inherited;
    while not Terminated do
      ComputeTheNextTenDigitsOfPi; // Takes 100 ms.
end;

Bad

procedure TMyThread.Execute;
begin
  inherited;
    while not Terminated do
      ComputeAVeryVeryLargeFractal; // Takes an hour.
                                    // And you will create the same fractal
                                    // over and over again.
end;
Andreas Rejbrand
Thank you for your help
+2  A: 

CodeInChaos offers some good advice in the comments - there are precious few situations where a thread should be terminated from outside.

Some thread environments have cancellation functions where you cancel (not kill) a thread and it will, when it is ready, kill itself. This allows the thread to set its own rules for when it's safe to be terminated.

The problem with external killing is that the target thread may have a resource lock which will now never be released, leading to potential deadlock.

The basic rule to follow is that all threads must check if they should be terminated in a timely fashion. In other words, if you're waiting for work, time out after five seconds in your loop and check the state:

do while not terminating:
    wait 2 seconds for work
    if not terminating and work available:
        do it

That particular thread will never take more than about two seconds to exit once the terminating flag has been set.

And, if do it is a long running task, you may also want to check periodically within that if you should exit as well.

paxdiablo
Thank you all for your help.
+5  A: 

If you must terminate the job - because it's blocked in code that you don't control, for example - then consider trying to wrap it up in a separate executable altogether, and run it as a sub-process, and terminate the process when you need it stopped. Processes have far stronger isolation than threads. Terminating a thread is a sure recipe for pain - what if the thread being terminated held a lock in the memory manager or somewhere similar? Next time you try to allocate memory (or similar), your app would be deadlocked!

Barry Kelly
+1 Brilliant as always!!
Fabricio Araujo