【问题标题】:How to close thread winapi如何关闭线程winapi
【发布时间】:2014-04-19 07:58:35
【问题描述】:

Winapi中关闭线程的正确方法是什么,线程不使用公共资源。 我正在使用 CreateThread 创建线程,但我不知道如何正确关闭它,因为有人建议使用 TerminateThread ,其他人使用 ExitThread ,但是关闭它的正确方法是什么。 另外我应该在哪里调用 WM_CLOSE 或 WM_DESTROY 的关闭函数? 提前谢谢。

【问题讨论】:

  • 第一个问题 - 您是否正在关闭您的应用程序,如果是,您是否需要“关闭”相关线程?是否保存必须刷新到磁盘的数据,或不能保持打开的数据库连接等?

标签: multithreading winapi


【解决方案1】:

在 Windows 中关闭线程的“最好”方法是通过某种线程安全的信号机制“告诉”线程关闭,然后简单地让它自行结束,可能等待它通过一个如果需要完成检测(通常是这种情况),则使用 WaitForXXXX 函数。比如:

主线程:

// some global event all threads can reach
ghStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

// create the child thread
hThread = CreateThread(NULL, 0, ThreadProc, NULL, 0, NULL);

//
// ... continue other work.
//

// tell thread to stop
SetEvent(ghStopEvent);

// now wait for thread to signal termination
WaitForSingleObject(hThread, INFINITE);

// important. close handles when no longer needed
CloseHandle(hThread);
CloseHandle(ghStopEvent);

子线程:

DWORD WINAPI ThreadProc(LPVOID pv)
{
    // do threaded work
    while (WaitForSingleObject(ghStopEvent, 1) == WAIT_TIMEOUT)
    {
         // do thread busy work
    }

    return 0;
}

显然,一旦您开始将其付诸实践,事情就会变得更加复杂。如果您所说的“公共”资源是指前面示例中的 ghStopEvent 之类的东西,那么它变得更加困难。 强烈不鼓励通过TerminateThread 终止子线程,因为根本没有执行逻辑清理`TerminateThread documentation 中指定的警告是不言自明的,应予以注意。强大的力量来了......

最后,即使是调用ExitThread调用 线程也不是明确要求,虽然你可以这样做,但我强烈在 C++ 程序中建议反对它。一旦线程过程从ThreadProc 逻辑返回,它就会被为你调用。我更喜欢上面的模型只是因为它很容易实现并且支持 C++ 对象清理的完整 RAII,ExitThreadTerminateThread 都不提供。例如,ExitThread 文档:

...在 C++ 代码中,线程在调用任何析构函数之前退出 或者可以执行任何其他自动清理。因此,在 C++ 代码,你应该从你的线程函数返回

无论如何,从简单开始。用超级简单的例子来处理事情,然后从那里开始。网络上有 多线程示例,向好的示例学习并挑战自己以识别坏的示例。

祝你好运。

【讨论】:

    【解决方案2】:

    所以你需要弄清楚你需要什么样的行为。

    以下是从文档中获取的方法的简单描述:

    "TerminateThread 是一个危险的函数,只应在最极端的情况下使用。只有在您确切知道目标线程在做什么并且您控制了目标线程可能执行的所有代码的情况下,您才应该调用 TerminateThread在终止时运行。例如,TerminateThread 可能会导致以下问题: 如果目标线程拥有临界区,该临界区将不会被释放。 如果目标线程正在从堆中分配内存,则不会释放堆锁。 如果目标线程在终止时正在执行某些 kernel32 调用,则线程进程的 kernel32 状态可能不一致。 如果目标线程正在操作共享 DLL 的全局状态,则 DLL 的状态可能会被破坏,从而影响 DLL 的其他用户。"

    因此,如果您需要不惜一切代价终止线程,请调用此方法。

    关于ExitThread,这个比较优雅。通过调用ExitThread,你告诉windows你已经完成了那个调用线程,所以其余的代码不会被调用。有点像调用exit(0)。

    "ExitThread 是退出线程的首选方法。当调用此函数时(显式调用或从线程过程返回),当前线程的堆栈被释放,线程发起的所有挂起的 I/O 都被取消,并且线程终止。如果调用此函数时线程是进程中的最后一个线程,则该线程的进程也终止。"

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多