【问题标题】:Is it necessary to explicitly stop all threads prior to exiting a Win32 application?是否有必要在退出 Win32 应用程序之前显式停止所有线程?
【发布时间】:2011-01-12 22:51:13
【问题描述】:

我有一个 Win32 本机 VC++ 应用程序,它在进入 WinMain() 时启动一个单独的线程,然后在另一个线程运行时执行一些有用的工作,然后简单地退出 WinMain() - 另一个线程没有显式停止。

This blog post 表示在这种情况下 .NET 应用程序不会终止,因为其他线程仍在运行。这同样适用于原生 Win32 应用程序吗?

我必须在退出之前停止所有线程吗?

【问题讨论】:

    标签: windows multithreading winapi visual-c++


    【解决方案1】:

    是的,如果您只是通过ExitThreadTerminateThread 退出或终止主线程,则必须这样做,否则您的应用程序可能无法完全关闭。我推荐阅读 Raymond Chen 关于这个主题的优秀博文:

    但请特别注意,如果您正确地从mainWinMain 函数返回,该过程将按照ExitProcess API documentation 和上面链接的Raymond Chen 的最后一篇文章的描述退出!

    【讨论】:

      【解决方案2】:

      我认为您可以先关闭所有窗口(这样用户就不会看到您的应用程序),然后设置退出标志,您的线程应该定期检查标志,一旦找到设置,线程应该返回。

      设置标志后,您的主线程可以调用 ::WaitForSingleObject() 或 ::WaitForMultipleObjects() 一段时间(例如,三秒钟),如果线程没有返回,只需通过 ::TerminateThread 杀死它们()。

      【讨论】:

        【解决方案3】:

        它的短处是: 要终止本机 Win32 进程,必须满足以下两个条件之一:

        • 有人调用 ExitProcess 或 TerminateProcess。
        • 所有线程退出(通过从它们的 ThreadProc 返回(包括 WinMainEntryPoint,它是 windows 创建的第一个线程))、关闭(通过调用 ExitThread)或终止(有人调用 TerminateThread)。

        (第一个条件其实和第二个一样:ExitProcess和TerminateProcess,作为它们清理的一部分,都在进程中的每个线程上调用TerminateThread)。

        c 运行时施加不同的条件:要终止 C/C++ 应用程序,您必须:

        • 从 main(或 WinMain)返回。
        • 调用exit()

        调用exit() 或从main() 返回都会导致c-runtime 调用ExitProcess()。这就是 c & c++ 应用程序在不清理线程的情况下退出的方式。我个人认为这是一件坏事。

        但是,非平凡的 Win32 进程永远不会终止,因为许多完美的、否则合理的 Win32 子系统会创建工作线程。 winsock、ole 等。并且不提供任何方法来导致这些线程自发关闭。

        【讨论】:

          【解决方案4】:

          不,当 WinMain 返回时,进程将被终止,这意味着进程产生的所有线程都应该被终止,尽管它们可能不会被优雅地关闭。

          但是,可能会在其他线程正在运行时终止主线程,从而导致应用程序仍在运行。如果您在 WinMain 中调用 ExitThread(不是 exitExitProcess),并且有正在运行的线程(最终由主线程创建),那么您可能会观察到这种行为。尽管如此,只要在WinMain中返回就会调用ExitProcess,这意味着所有线程都应该被终止。

          如有错误请指正。

          【讨论】:

          • 这里给出的解释是100%正确的。我验证了 WinMain 线程是由 C 运行时创建的,当线程退出称为 ExitProcess 的 C 运行时,导致整个应用程序终止(包括其他线程)。
          【解决方案5】:

          简短回答:是的

          【讨论】:

            猜你喜欢
            • 2012-05-07
            • 2011-12-24
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-11-21
            • 1970-01-01
            • 1970-01-01
            • 2011-04-30
            相关资源
            最近更新 更多