当进程结束时,Sleep()中间的线程会发生什么?

时间:2014-02-18 17:14:53

标签: c++ c multithreading visual-c++ process

我正在使用一个开始和结束线程的类。线程在构造函数中创建。线程函数有一个循环,只要标志为TRUE就会继续。该标志是该类的静态成员。解构函数将标志设置为FALSE。这样,类的每个实例都有一个关联的线程,该线程在实例的生命周期内运行。

我试图绕过解构器运行时发生的事情,如果这是一个结束线程的好方法。我对多线程没有多少经验。

这就是我认为发生的事情。在解构器内部,标志将设置为FALSE。我们假设Sleep()正在为无穷大运行。该对象被销毁,但该标志仍然存在于内存中,因为它是静态的。但是,整个过程即将结束,所以在某些时候,静态标志将会消失。国旗会在线程之前消失吗?如果线程被进程结束强制返回,那么线程是否会再关心该标志?我不知道此时发生了什么。

我在Visual Studio 2010中使用Visual C ++。

3 个答案:

答案 0 :(得分:2)

在Windows上,线程的生命周期小于或等于其被终止的过程。因此,一旦过程结束,线程也就这样结束。

在该进程中的所有线程终止之前,不会完成正常的进程关闭。因此,在这种情况下将设置标志,主线程可以终止,但创建的后台线程将继续运行。最终,他们将看到标志的FALSE值,退出循环,完成并且过程关闭将完成。

答案 1 :(得分:2)

请注意,当某个其他线程仍在使用该对象(而不是静态标志)时运行析构函数将产生未定义的结果。

想一想当线程处于处理中间时发生的事情,而不是检查活标志,非常渺茫的机会吧。

最好写一个stop(bool wait)函数,所以如果析构函数被调用并需要自动清理,你可以设置标志停止,并阻塞直到线程将另一个标志设置为“停止”,或者只需使用pthread_join加入该线程(不推荐,见下文)。

此外,当您阻止正常终止时,您也可以设置超时,并在出现问题时强制终止线程(并为调试生成警报)。

答案 2 :(得分:0)

这取决于'解构主义者'是否实际运行。

如果你试图“解构”你在某个'OnClose'事件处理程序中描述的对象,设置静态标志将指示线程在它们检查它时终止。如果他们不这样做,线程将继续休眠,(或者仍然停留在阻塞的任何呼叫上,或者继续运行代码)。

如果不采取进一步操作等待对象线程终止,主GUI线程将继续运行,销毁其所有GUI对象等,并调用ExitProcess()。

一旦调用了ExitProcess(),操作系统将在释放任何内存之前停止进程的所有线程,无论它们处于什么状态,(如包含您的标志的内存)。

调用ExitProcess()的线程永远不会有控制权返回给它。属于同一进程但未在另一个核心上运行的其他线程的状态设置为永不再运行。属于同一进程并在另一个核心上运行的其他线程具有在硬件上运行的核心,以阻止线程。

  

该标志会在线程之前消失吗?

没有。在释放托管标志的内存之前,线程将被停止。

如果您不希望发生强制终止,则必须采取措施等待对象线程的实际终止。您必须通过在OnClose处理程序中设置适当的CloseAction来延迟主GUI线程调用ExitProcess。只有当所有对象线程都已终止且对象的析构函数已完成时,GUI线程才应关闭/释放。

如果我真的,真的,真的必须这样做,更喜欢通过PostMessaging一个'WM_THREADGONE'Windows消息到主GUI线程,(作为实际终止自己之前的对象线程的最后一个动作),以及在消息处理程序中向下计数'threadCount'为零,因此保持GUI线程可用于处理消息,直到所有对象线程都自行终止。 Hard-Wait机制,比如Join(),只是死锁生成器,具有很大的关闭问题容量,不应该使用。

我通常会尝试通过设计我的应用来解决所有线程终止问题,以便突然的,非自愿的线程终止是一个可接受的操作,然后让Exitprocess()将所有内容都吹走。这并不总是可行的,但是如果你可以侥幸逃脱它,那就更安全了。