安全地停止线程

use*_*256 7 c++ winapi multithreading

我写多线程程序.

我想问一下TerminateThread和之间的区别是ExitThread什么?

WM_DESTROY收到时这是我的代码段:

void CleanAll()
{
    DWORD dwExit[MAX_THREAD];
    for(int i = 0; i < MAX_THREAD; i++)
    {
        GetExitCodeThread(hThread[i], &dwExit[i]);
        // I used ExitThread(dwExit[i]); previously
        TerminateThread(hThread[i], dwExit[i]);
        CloseHandle(hThread[i]);
    }
}
Run Code Online (Sandbox Code Playgroud)

ExitThread()之前使用过,但是我的程序在任务管理器中激活,所以我将其更改为,TerminateThread()并且我的程序已从任务管理器中删除.

任何提前解释都非常感谢.

sel*_*bie 10

TerminateThread强制另一个线程退出.你应该不惜一切代价避免调用它,因为它会阻止一个线程死在它的轨道上而没有任何机会清理.这包括分配的任何CRT内存.

ExitThread用于当前正在运行的线程,以保持自己的干净利落.当您在上面调用它时,您可能会强制主(UI)线程退出,并且可能使正在运行的线程仍然在四处挥动.因此,您的程序仍在运行,如任务管理器中所示.由于线程实际上没有退出,因此GetExitCodeThread也可能失败.

但是,阻止线程的正确方法是通过任何必要的干净方式干净地发出信号,它应该退出. 然后允许线程在允许主线程退出之前自行退出.在下面的示例中,我使用了一个全局标志来向线程指示它们应该退出.但这假设你的线程总是有机会轮询全局bool状态.另一个更简洁的方法是让每个线程在事件句柄上调用WaitForSingleObject.发出事件句柄信号时,线程会检查全局变量并在需要时退出.

bool global_Need_ToExit;  // use a bool or replace with an event handle the thread shoudl wait on

void CleanAll()
{
    //signal all threads to exit
    global_Need_ToExit = true;

    DWORD dwExit[MAX_THREAD];
    for(int i = 0; i < MAX_THREAD; i++)
    {
        // actually wait for the thread to exit
        WaitForSingleObject(hThread[i], WAIT_INFINITE);

        // get the thread's exit code (I'm not sure why you need it)
        GetExitCodeThread(hThread[i], &dwExit[i]);

        // cleanup the thread
        CloseHandle(hThread[i]);
        hThread[i] = NULL;
    }
}

DWORD __stdcall YourThreadFunction(void* pData)
{

    while (global_Need_To_Exit == false)
    {
        // do more work
    }

    return 0; // same as ExitThread(0);
}
Run Code Online (Sandbox Code Playgroud)

  • 对于cancallation标记,而不是使用在不同编译器中具有不同含义的`volatile`,我使用`std :: atomic <bool>`.我认为不需要条件变量. (2认同)

小智 5

抱歉,但投票最高的答案说使用 ExitThread,因为它会“干净利落地自行停止”。这是不正确的。文档指出: ExitThread 是 C 代码中退出线程的首选方法。但是,在 C++ 代码中,线程会在调用任何析构函数或执行任何其他自动清理之前退出。因此,在 C++ 代码中,您应该从线程函数返回。 我通过遵循论坛的建议使用 ExitThread,然后花了几个小时想知道我所有的内存泄漏到底从何而来,才学到了这一点。是的,那是针对 C++ 的,但这就是这个问题所涉及的。实际上,即使对于 C,也有一个警告“链接到静态 C 运行时库 (CRT) 的可执行文件中的线程应该使用 _beginthread 和 _endthread 进行线程管理,而不是 CreateThread 和 ExitThread。不这样做会导致当线程调用 ExitThread 时,会出现少量内存泄漏。” 不要在不知道后果的情况下使用 ExitThread!


jwe*_*ich 2

当你的线程完成时,你的进程应该完成吗?对于您所描述的问题可能有很多解释。如果你想终止整个进程,只需调用ExitProcess.

问题TerminateThread是这很可能导致内存泄漏。它不关心线程状态,也不关心其分配的资源。它还可能导致死锁,具体取决于您进行同步的方式。换句话说,它不会优雅地终止它。

终止线程的最佳方法是不显式终止它。不要调用TerminateThreadnor ExitThread,而只是return从线程的函数中调用。您可能需要使用原子标志,或触发事件(或其他同步方法)来发出线程何时应终止的信号。然后你的线程应该定期检查该标志(或事件)并在返回(终止)之前释放所有资源。