[关于超时] 一个简单的问题难道了无数高手=============================================================
一个人正在跑步,这时候你命令他停下来,结果是这个人肯定会停下来.
问题是:如果他的一条腿还没有着地呢?
1: 保持一条腿还在空中在
2: 等待这条腿落地后立即停下来 在现实生活中这个人肯定会等待那条腿落地后才停下来
那么在程序中是这样吗?
============================================================= 在window API中有些函数执行需要很长一段时间才返回结果
我们有时候需要在指定的时间内没有返回的话,就停止函数执行.一般我们可以用WaitForSingleObject来设置超时,
但是这个函数没有句柄啊?用WaitForSingleObject也许不行.
[如果你认为行,或者知道其它方法的人请指教]于是我想,把这个函数放在一个线程mythread中
function mythread
begin
APIfun1;//比如这个API函数要30秒钟才能返回
other code;
... ...
end;在主程序中,从CreatThread的时候开始计时;
如果到了指定的时间timeout没有放回结果的话,
就TerminateThread 终止线程那么现在问题就出现了:
我相信windows肯定会终止这个线程
但是这个线程是否要等待这个函数执行完毕后才终止呢?
这样说不知道大家明白了没有?
还没有明白的朋友请再次看前面的比喻.function mythread
//下面把线程函数分成三个部分看起来,更容易理解
begin
//---------------------------------------------- //此时如果主程序终止线程,那么没有什么疑问;肯定会立即终止的, //---------------------------------------------- APIfun1; //比如这个API函数要60秒钟才能返回
// 问题是APIfun1正在执行,是执行完毕后退出,还是立即退出???
//---------------------------------------------- //此时如果主程序终止线程,那么没有什么疑问;肯定会立即终止的, //--------------------------------------------- other code; //------------------------------------------
... ...
end;
也许你要问,能不还具体一点?
好的我给个实际的API函数的例子你
function NetUse(ip):boolean;
var
NRW: TNetResource; Res: Dword;
begin
with NRW do
begin
dwType := RESOURCETYPE_ANY;
lpRemoteName := pchar('\\'+ip+'\ipc$');
lpLocalName := '';
lpProvider := '';
end;
Res := WNetAddConnection2(NRW, '', '', 0);
if Res = No_Error then result:=true else result:=false;
end;===================================================
仁者见仁,智者见智,请勿灌水.
===================================================
一个人正在跑步,这时候你命令他停下来,结果是这个人肯定会停下来.
问题是:如果他的一条腿还没有着地呢?
1: 保持一条腿还在空中在
2: 等待这条腿落地后立即停下来 在现实生活中这个人肯定会等待那条腿落地后才停下来
那么在程序中是这样吗?
============================================================= 在window API中有些函数执行需要很长一段时间才返回结果
我们有时候需要在指定的时间内没有返回的话,就停止函数执行.一般我们可以用WaitForSingleObject来设置超时,
但是这个函数没有句柄啊?用WaitForSingleObject也许不行.
[如果你认为行,或者知道其它方法的人请指教]于是我想,把这个函数放在一个线程mythread中
function mythread
begin
APIfun1;//比如这个API函数要30秒钟才能返回
other code;
... ...
end;在主程序中,从CreatThread的时候开始计时;
如果到了指定的时间timeout没有放回结果的话,
就TerminateThread 终止线程那么现在问题就出现了:
我相信windows肯定会终止这个线程
但是这个线程是否要等待这个函数执行完毕后才终止呢?
这样说不知道大家明白了没有?
还没有明白的朋友请再次看前面的比喻.function mythread
//下面把线程函数分成三个部分看起来,更容易理解
begin
//---------------------------------------------- //此时如果主程序终止线程,那么没有什么疑问;肯定会立即终止的, //---------------------------------------------- APIfun1; //比如这个API函数要60秒钟才能返回
// 问题是APIfun1正在执行,是执行完毕后退出,还是立即退出???
//---------------------------------------------- //此时如果主程序终止线程,那么没有什么疑问;肯定会立即终止的, //--------------------------------------------- other code; //------------------------------------------
... ...
end;
也许你要问,能不还具体一点?
好的我给个实际的API函数的例子你
function NetUse(ip):boolean;
var
NRW: TNetResource; Res: Dword;
begin
with NRW do
begin
dwType := RESOURCETYPE_ANY;
lpRemoteName := pchar('\\'+ip+'\ipc$');
lpLocalName := '';
lpProvider := '';
end;
Res := WNetAddConnection2(NRW, '', '', 0);
if Res = No_Error then result:=true else result:=false;
end;===================================================
仁者见仁,智者见智,请勿灌水.
===================================================
dwTime:=GetTickCount();
APIFunc(handle,...)
end;thread2func()/Timer
if GetTickCount()-dwTime>overtime then
closehandle(handle); //APIFunc return;
你看Windows的进程管理器
大家继续
学习ing
楼主如果要硬行终止一个线程,可以用 TerminateThread() API 啊。
==================================
看了你们的解答;发现你们还没有明白我的意思
关于如何计时和如何终止线程不是本问题的关键
进程会不会终止也不是问题的关键
TerminateThread进程肯定会终止的,这是没有任何疑问的!关键在于进程是马上结束这个API,还是等这个API运行完毕后在结束进程
==================================
请大家理解了题目再做回答!!!==================================
在线程中用GetTickCount测试一个比较大的循环,然后比较正常结束线程所花的时间和用TerminateThread强行结束所花的时间...
您的解答我很满意!但是我有个疑问:
您开始说“Windows根本不关心线程处于什么状态,他活生生的把线程杀了,把线程的堆栈收回了”
如果这样的话,线程应该马上终止;
但是您后面又说“后备线程,直到进程结束或者程序的其他部分关闭它的时候才会得到关闭。”
这么说线程还没有完全终止???
是否有点自相矛盾?请您再次指点!谢谢
----------------------------------
我又想到一个相关的问题:
比如我们在编写多线程的时候
如果线程超时就TerminateThread,并保持线程总数不超过制定数量(比如300)个
如果TerminateThread不能保证真正的终止的化,
那么我们设置的最大线程数就是自欺欺人!!!
----------------------------------
就是想知道一个线程如果在做需要很长时间才能结束的任务的话,当TerminateThread命令它终止时,是不是会马上终止。
这个当然是马上终止的啊,不管它是在做一个for循环运算还是正处于它所调用的某个API里面,它都会马上终止的。因为TerminateThread是直接挂起线程,然后销毁线程的一切,不管它正在做什么。即使它正处于某个API里面,又怎么样呢?那个API或者说某个DLL的函数代码在内存里是“死”的啊,被这个线程运行了之后才“活”过来的,既然线程被CPU挂起了,当然就不会再向下运行任何语句。就像一个人在跑步,当他一条腿还在空中的时候,你把他的时间暂停了(就像恐龙特急克塞号),然后把他“销毁”了,他已经不存在了,他的腿还怎么落地呢?
写个程序测试一下,看Windows是怎 么处理的。我想也不是绝对的,就是说有的线程会立即终止,但有的则不然,看Windows怎么处理了,如果这时Windows觉得产即结束他是安全的,那它就会这样做,否则可能会等待到一个安全时刻才结束。立即终止线程是不安全的。将造成无法预料的后果。估计WINDOWS会考虑到这一点,例如:根据当前线线程的内配分配情况来决定等。具体可以参考MSDN
在Java的早期版本里面,提供了立即终止线程的方法(suspend(),stop())。
但从Java2后,官方文档中强调,这样调用是不安全,不赞成这样处理,而有join()方法等待线程结束,这种方法被认为是安全的。
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 is doing, and you control all of the code that the target thread could possibly be running at the time of the termination. For example, TerminateThread can result in the following problems:· If the target thread owns a critical section, the critical section will not be released.
· If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
· If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL. A thread cannot protect itself against TerminateThread, other than by controlling access to its handles. The thread handle returned by the CreateThread and CreateProcess functions has THREAD_TERMINATE access, so any caller holding one of these handles can terminate your thread.
If the target thread is the last thread of a process when this function is called, the thread's process is also terminated.
The state of the thread object becomes signaled, releasing any other threads that had been waiting for the thread to terminate. The thread's termination status changes from STILL_ACTIVE to the value of the dwExitCode parameter. Terminating a thread does not necessarily remove the thread object from the system. A thread object is deleted when the last thread handle is closed.
坚决反对使用terminatethread