TerminateThread的疑问,请高手解释一下,谢谢!(50分)

  • 主题发起人 主题发起人 hotreg
  • 开始时间 开始时间
H

hotreg

Unregistered / Unconfirmed
GUEST, unregistred user!
我现在用这个函数可以很快的停止一线程,是不是线程运行到哪里都会被立即停止,
不再运行后面的代码,该过程的是否会激活什么事件?
 
该过程什么都不会激发,最好少用
 
to:张无忌
ics控件中的wsocket使用以下的代码等待WM_QUIT来退出消息循环。
procedure TCustomWSocket.MessageLoop;
var
MsgRec : TMsg;
begin
{ If GetMessage retrieves the WM_QUIT, the return value is FALSE and }
{ the message loop is broken. }
while GetMessage(MsgRec, 0, 0, 0)do
begin
TranslateMessage(MsgRec);
DispatchMessage(MsgRec)
end;
FTerminated := TRUE;
end;

我的的程序中的每个线程都使用了一个wsocket,如果少量的线程,我可以通过发送
PostThreadMessage(g_Thread[l_ThrdID - 1].ThreadID, WM_QUIT, 0, 0);
退出MessageLoop循环,但如果线程数量大的话,如50-60个,是否就很难停止每个线程(目前我的程序就是这样),但如果使用TerminateThread,确实可以立即停止线程,但线程中的一些代码就无法处理了,请老兄指点一下,万分感谢!!!!!!

 
你又想安全,又想快速。哪有那么好的事情.
TerminateThread是你在紧急情况下用的
 
下面这段Delphi的帮助你能看懂吧!
TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code and its initial stack is not deallocated. DLLs attached to the thread are not notified that the thread is terminating.
TerminateThread is a dangerous function that should only be used in the most extreme cases. You should call TerminateThread only if you know exactly what the target thread isdo
ing, and you control all of the code that the target thread could possibly be running at the time of the termination.
 
感谢大家的解释,现在的问题是,我的程序最多可能同时运行60个线程,我们先不考虑
这样是否有必要,先考虑这样60个线程同时运行时,
我用PostThreadMessage(g_Thread[l_ThrdID - 1].ThreadID, WM_QUIT, 0, 0);发消息给每个线程的消息循环,是否每个线程都可以准确的接收到?
getmessage(...)是不是可以很好的接受到消息,有没有效率更高的函数。
有谁在程序中开过这么多的线程的,能否给点经验,谢谢!!!
 
其实不需要API,直接用terminate过程就可以了
在EXECUTE循环里不断检测,不过在检测之前就阻塞的话就没办法了,
只能用TERMINATETHREAD,
 
什么情况下会造成阻塞呢?每个线程中的getmessage(...)等待消息时会吗?
如何判断已经造成阻塞了?
 
你最好自定义一个消息;然后在接受到这个消息后
PostQuitMessage(0);
结束线程.
MSDN不推荐用PostMessage函数发送WM_QUIT消息.
 
to: xeen
非常感谢,你这个说法我还是第一次看到,
我是不是要修改ics的原代码,就是他接收WM_QUIT消息的messageloop过程
procedure TCustomWSocket.MessageLoop;
var
MsgRec : TMsg;
begin
{ If GetMessage retrieves the WM_QUIT, the return value is FALSE and }
{ the message loop is broken. }
while GetMessage(MsgRec, 0, 0, 0)do
begin
TranslateMessage(MsgRec);
DispatchMessage(MsgRec)
end;
FTerminated := TRUE;
end;
要如何修改,能给点简单的代码吗?谢谢!!
 
我没用过ICS,你的MsgRec被发到那个过程中处理了?
在一个特定的过程中PostQuitMessage(0);即可.
 
TerminateThread是立即结束(杀死)线程用的,但是它不会释放线程占用的资源,要想释放这些资源还得在TerminateThread后执行线程的Terminate方法。
 
>>你的MsgRec被发到那个过程中处理了?
我不能理解你说的,抱歉
我现在是在主程序发WM_Quit消息给每个线程中的 messageloop 过程,
每个线程收到WM_Quit后,就要退出 messageloop 过程,
按您说法,我要在哪里增加一个自定义的消息,又要在哪里发PostQuitMessage(0);
 
这样.
CONST MyQuitMessage =WM_USER + 1;
procedure TCustomWSocket.MessageLoop;
var
MsgRec : TMsg;
begin
{ If GetMessage retrieves the WM_QUIT, the return value is FALSE and }
{ the message loop is broken. }
while GetMessage(MsgRec, 0, 0, 0)do
begin
if MsgRec.message = MyQuitMessage then
PostQuitMessage(0)
else
begin
TranslateMessage(MsgRec);
DispatchMessage(MsgRec);
end;
end;
FTerminated := TRUE;
end;
在其他线程中:
PostThreadMessage(g_Thread[l_ThrdID - 1].ThreadID, MyQuitMessage, 0, 0);
 
to: xeen
我试一下,非常感谢!!!
 
在terminatethread函数执行完成了以后,线程中的回调函数就已经停止了,这个时候,如果在该回调函数里申请的内存将没有办法被释放,除非这些内存的句柄已经在回调函数外被记录过,但是,该TThread对象中所申请的内存还是可以使用TThread.Free来释放的。所以说,如果想使用TerminateThread来停止线程的话,则所有的内存的申请都在TThread.Create中申请,在TThread.Destroy中释放,这样我想应该也是安全的,否则,在TThread.Execute方法中,就只能使用一个消息循环,当检查到Terminated属性为真时就退出(这也是BORLAND推荐的方法)但是如果遇到了阴塞的时候,就没有办法结束一个线程了,比如说在accept()API函数的时候(该函数是SOCKET中的一个函数,当没有客户端连接上来的话则会一直等待,不返回)是没有办法取得控制权的,这个时候靠Terminated这个属性是没有办法让线程停止下来。
两种方法,大家可以讨论讨论。如果我有不对的地方,还请批评
 
accept的时候,组塞了,你可以用closesocket()就可以使他返回,这么就可以关掉线程
反正总有办法可以使线程安全的推出,楼上说的哪个函数根本就没有要,
 
楼上的能够保证所有的阻塞都可以有办法停得下来吗?
比如说,别人的控件,或者是说一些搜索的函数等等,如果需要马上返回的话,是不是马上能够停得下来?如果不是的话,还是得使用TerminateThread这个函数,即然这个函数存在,就会有一定的道理的,如果说根本没有必要的话,未免也太武断了
 
扫描函数我可以设置标志什么的,别人的控件我可以把他代码修改,总是有办法的
那上面的哪个函数太危险了,除非是万不的一,我是不用的,要用的话我就干脆整
个程序都推出算了
 
对于线程的退出,我一般是用WaitFor(TimeOut)这个我把DELPHI的线程类给修改了
我加了个超时。。。如果超过了哪个时间,在用上面说的函数,
 
后退
顶部