Yesterday experts advised using "while not terminated do begin..." in thread exe开发者_Python百科cute 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.
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;
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!
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. Or, even if resources are freed on thread exit, the data in that resource may no longer be consistent.
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 some number of 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.
精彩评论