山之人 發表於 2019-11-13 19:34:00

Delphi线程的终止

<p>转载自:https://www.cnblogs.com/xumenger/p/4440646.html</p>
<p>当线程对象的Execute()执行完毕,我们就认为此线程终止了。这时候,它会调用Delphi的一个标准例程EndThread(),这个例程再调用API函数ExitThread()。由ExitThread()来清除线程所占用的栈。</p>
<p>  当结束使用TThread对象时,应该确保已经把这个Delphi对象从内存中清除了。这才能确保所有内存占有都释放掉。<strong>尽管在进程终止时会自动清除所有的线程对象,但是及时清除已经不再使用的对象,可以使内存的使用效率提高</strong>。利用将FreeOnTerminate的属性设置为True的方法来及时清除线程对象时最方便的方法,这只需要在Execute()退出之前设置就行了。设置的方法如下</p>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_132317" class="syntaxhighlighterdelphi">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="delphi keyword">procedure</code>&nbsp;<code class="delphi plain">TTestThread</code><code class="delphi value">.</code><code class="delphi plain">Execute;</code></div>
<div class="line number2 index1 alt1"><code class="delphi keyword">var</code></div>
<div class="line number3 index2 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">i:&nbsp;</code><code class="delphi keyword">Integer</code><code class="delphi plain">;</code></div>
<div class="line number4 index3 alt1"><code class="delphi keyword">begin</code></div>
<div class="line number5 index4 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">FreeOnTerminate:=&nbsp;</code><code class="delphi keyword">True</code><code class="delphi plain">;</code></div>
<div class="line number6 index5 alt1"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi keyword">for</code>&nbsp;<code class="delphi plain">i:=</code><code class="delphi value">1</code>&nbsp;<code class="delphi keyword">to</code>&nbsp;<code class="delphi value">2000000</code>&nbsp;<code class="delphi keyword">do</code></div>
<div class="line number7 index6 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">inc(Answer, Round(</code><code class="delphi keyword">Abs</code><code class="delphi plain">(Sin(Sqrt(i)))));</code></div>
<div class="line number8 index7 alt1"><code class="delphi keyword">end</code><code class="delphi plain">;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>  这样,当一个线程终止的时候,就会触发OnTerminate事件,就会有机会在事件处理过程中清除线程对象了。</p>
<p>  提示:OnTerminate事件是在主线程的环境中发生的。这就意味着,在处理这个事件的过程中,你可以不需要借助于Synchronize()而自由地访问VCL</p>
<p>&nbsp;</p>
<p>  <strong>要记住Execute()需要经常地检查Terminated属性的值,来确认是否要提前退出。尽管这将意味着当使用线程工作的时候,你必须关心更多的事情,但它能确保在线程结束时,能够完成必要的清除。</strong>下面是一段在Execute()增加处理操作的简单代码:</p>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_232314" class="syntaxhighlighterdelphi">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
<div class="line number2 index1 alt1">2</div>
<div class="line number3 index2 alt2">3</div>
<div class="line number4 index3 alt1">4</div>
<div class="line number5 index4 alt2">5</div>
<div class="line number6 index5 alt1">6</div>
<div class="line number7 index6 alt2">7</div>
<div class="line number8 index7 alt1">8</div>
<div class="line number9 index8 alt2">9</div>
<div class="line number10 index9 alt1">10</div>
<div class="line number11 index10 alt2">11</div>
<div class="line number12 index11 alt1">12</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="delphi keyword">procedure</code>&nbsp;<code class="delphi plain">TTestThread</code><code class="delphi value">.</code><code class="delphi plain">Execute;</code></div>
<div class="line number2 index1 alt1"><code class="delphi keyword">var</code></div>
<div class="line number3 index2 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">i:&nbsp;</code><code class="delphi keyword">Integer</code><code class="delphi plain">;</code></div>
<div class="line number4 index3 alt1"><code class="delphi keyword">begin</code></div>
<div class="line number5 index4 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">FreeOnTerminate:=&nbsp;</code><code class="delphi keyword">True</code><code class="delphi plain">;</code></div>
<div class="line number6 index5 alt1"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi keyword">for</code>&nbsp;<code class="delphi plain">i:=&nbsp;</code><code class="delphi value">1</code>&nbsp;<code class="delphi keyword">to</code>&nbsp;<code class="delphi value">2000000</code>&nbsp;<code class="delphi keyword">do</code></div>
<div class="line number7 index6 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi keyword">begin</code></div>
<div class="line number8 index7 alt1"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi keyword">if</code>&nbsp;<code class="delphi plain">Terminated&nbsp;</code><code class="delphi keyword">then</code></div>
<div class="line number9 index8 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">break;</code></div>
<div class="line number10 index9 alt1"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi plain">inc(Answer, Round(</code><code class="delphi keyword">Abs</code><code class="delphi plain">(Sin(Sqrt(i)))));</code></div>
<div class="line number11 index10 alt2"><code class="delphi spaces">&nbsp;&nbsp;&nbsp;&nbsp;</code><code class="delphi keyword">end</code><code class="delphi plain">;</code></div>
<div class="line number12 index11 alt1"><code class="delphi keyword">end</code><code class="delphi plain">;</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>  注意,在某些紧急情况下,你可以使用Win32 API函数 TerminateThread()来终止一个线程。但是,除非没有别的办法了,否则不要使用它。例如,当线程代码陷入死循环中。TerminateThread()的声明如下</p>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_310768" class="syntaxhighlighterdelphi">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="delphi keyword">function</code>&nbsp;<code class="delphi plain">TerminateThread(hThread: THandle; dwExitCode: DWORD);</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>  TThread的Handle属性可以作为第一个参数,因此,TerminateThread()常这样调用</p>
<div class="cnblogs_Highlighter sh-gutter">
<div>
<div id="highlighter_364279" class="syntaxhighlighterdelphi">
<table border="0" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td class="gutter">
<div class="line number1 index0 alt2">1</div>
</td>
<td class="code">
<div class="container">
<div class="line number1 index0 alt2"><code class="delphi plain">TerminateThread(MyHosedThread</code><code class="delphi value">.</code><code class="delphi plain">Handle,&nbsp;</code><code class="delphi value">0</code><code class="delphi plain">);</code></div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<p>  如果选择这个函数,应该考虑到它的负面影响。首先,此函数在Windows NT与在Windows95/98下并不相同。在Windows95/98下,这个函数能够自动清除线程所占用的栈;而在Windows NT下,在进程被终止前栈仍被保留。其次,无论线程代码中是否有try...finally块,这个函数都会使线程立即终止执行。这意味着,被线程打开的文件没有被关闭、由线程申请的内存也没有被释放等情况。而且,这个函数在终止线程的时候也不通知DLL,当DLL关闭的时候,这也容易出现enti问题</p><br><br>
来源:https://www.cnblogs.com/approx/p/11852082.html
頁: [1]
查看完整版本: Delphi线程的终止