难道真的没有办法从外部中断线程且不造成资源泄漏?
首先介绍下背景,我的线程是我自己创建的,里面需要用到复杂的算法,但完全不需要系统调用(当然也不需要分配内存)。你可以把他假想为一个对大量数据排序的算法。
另外我的线程有一定的实时性要求,可以认为系统有一个电眼提供外部触发信号,在下一个触发信号到达前,必须处理完当前信号。
目前考虑有3种办法:
1、在复杂算法内部经常性去判断下一个触发信号是否已到达,流程大致如下:
算法步骤1;
下一信号是否到达?到达则返回;
算法步骤2;
下一信号是否到达?到达则返回;
算法步骤3;
下一信号是否到达?到达则返回;
......
缺点:算法本身相当复杂,并不好简单的分为几个步骤,且相邻两次检查信号之间的步骤会运行多久,也很难估计(每次信号不同,使得算法每个步骤需要的时间也可能不同),这样就有可能下一信号已经到达一段时间后,才会停止处理当前信号。当前信号晚点处理完倒没什么关系,反正结果都没用了。但问题是可能造成下一种办法提到的连锁反应。
另外这种做法本身对算法程序的独立性/维护性都会造成影响。
2、不终止当前信号的线程,让它自然结束。新建线程处理新的信号。
缺点:系统负荷不大时,这也是个办法。但系统负荷较大时,很可能当前信号的线程占用CPU,导致下一信号也不能被及时处理,从而造成连锁反应。甚至可能系统中线程越来越多,最终崩溃。
3、在下一个触发信号到达时,如果当前信号未处理结束则使用TerminateThread强行终止。
这个方法应该能够克服上面的两个缺点,但查了好几天,都说TerminateThread会造成泄漏。
《Windows 核心编程》提到,线程函数返回时能够确保:
1.在线程函数中创建的所有C + +对象均将通过它们的撤消函数正确地撤消。
2.操作系统将正确地释放线程堆栈使用的内存。
3.系统将线程的退出代码(在线程的内核对象中维护)设置为线程函数的返回值。
4.系统将递减线程内核对象的使用计数。
由于我的线程不会分配内存,所以主要问题应该在“释放线程堆栈”和“递减线程内核对象的使用计数”。
我的问题是:
1.确实没有办法TerminateThread后释放线程堆栈吗?
2.TerminateThread后,通过CloseHandle是否可以达到“递减线程内核对象的使用计数”的效果?
我觉得我的这个需求在一些需要实时进行产品检测的流水线上是很常见的,应该有比较好的解决办法才对。
期望高手给予解答,非常感谢!
分不够了,惭愧
[解决办法]
DWORD WINAPI threadFunc(LPVOID pParam);
int main()
{
HANDLE hThread;CONTEXT context;
hThread = CreateThread(NULL,
0,
threadFunc,
0,0,
0);
while(1)
{
getch();
SuspendThread(hThread);
context.ContextFlags=CONTEXT_CONTROL;
GetThreadContext(hThread,&context);
context.EFlags|=0x100;
SetThreadContext(hThread,&context);
ResumeThread(hThread);
}
return 0;
}
DWORD WINAPI threadFunc(LPVOID pParam)
{
d:
__try
{
while(1)SwitchToThread();
}__except(EXCEPTION_EXECUTE_HANDLER)
{
cout<<"sdf"<<endl;
goto d;
}
return 0;
}