如果我们强行杀死正在运行的线程会发生什么
我有一个线程RecordThread()
,它调用了一些复杂且耗时的函数。在这些函数中,我使用 try-catch 块,分配和释放内存以及使用关键部分变量等。
像
void RecordThread()
{
AddRecord();
FindRecord();
DeleteRecord();
// ...
ExitThread(0);
}
创建此线程后,我会在线程完成执行之前立即将其删除。在这种情况下,如果强行杀死线程会发生什么?在我们杀死线程后,内部函数(AddRecord
,DeleteRecord
)是否完成执行?
答案 0 :(得分:13)
创建此线程后,我会在线程完成执行之前立即将其删除。
我认为您的意思是您正在以下列方式使用TerminateThread()
:
HANDLE thread = CreateThread(...);
// ...
// short pause or other action?
// ...
TerminateThread(thread, 0); // Dangerous source of errors!
CloseHandle(thread);
如果是这种情况,那么执行RecordThread()
的线程将在另一个线程调用TerminateThread()
时完全停止。根据{{3}}文档中的注释,这个确切点有点随机,取决于您无法控制的复杂时序问题。这意味着您无法在线程内部进行正确的清理,因此TerminateThread()
。
请求线程完成的正确方法是使用WaitForSingleObject()
,如下所示:
HANDLE thread = CreateThread(...);
// ...
// some other action?
// ...
// you can pass a short timeout instead and kill the thread if it hasn't
// completed when the timeout expires.
WaitForSingleObject(thread, INFINITE);
CloseHandle(thread);
答案 1 :(得分:3)
杀死线程是最后的手段 - 正如安德烈所说,它将数据保留为未知状态,如果线程在共享对象上运行,则不应该这样做。更好的选择是通过以下方式通知线程完成工作:
- 使用全局 volatile (重要)变量,该变量仅由主线程更改并由工作人员测试
- 使用信号类型同步对象(主要是事件)也由主线程设置并由工作人员测试
答案 2 :(得分:2)
http://msdn.microsoft.com/en-us/library/windows/desktop/ms682659%28v=vs.85%29.aspx
ExitThread是退出C代码中线程的首选方法。但是,在C ++代码中,在可以调用任何析构函数之前退出线程,或者可以执行任何其他自动清理。因此,在C ++代码中,您应该从线程函数返回。
然而,函数调用当然会完成,因为它们是在ExitThread()之前调用的。
答案 3 :(得分:0)
运行良好的线程示例:
definition in *.h ------------------------------------
DWORD WINAPI Th_EspectroIF(LPVOID lpData);
CThread th_espectro(Th_EspectroIF);
use in *.cc -----------------------------------
DWORD WINAPI Th_EspectroIF(LPVOID lpData)
{
//Your code...
th_espectro.Stop(true);//stop this Thread
}
使用以下命令调用线程: th_espectro.Start();