杀死正在运行的线程

时间:2012-05-24 12:23:12

标签: c++ windows multithreading

如果我们强行杀死正在运行的线程会发生什么

我有一个线程RecordThread(),它调用了一些复杂且耗时的函数。在这些函数中,我使用 try-catch 块,分配和释放内存以及使用关键部分变量等。

  void RecordThread()
  {
    AddRecord();
    FindRecord();
    DeleteRecord();
    // ...
    ExitThread(0);
   } 

创建此线程后,我会在线程完成执行之前立即将其删除。在这种情况下,如果强行杀死线程会发生什么?在我们杀死线程后,内部函数(AddRecordDeleteRecord)是否完成执行?

4 个答案:

答案 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();