【问题标题】:How to make a new thread and terminate it after some time has elapsed?如何创建一个新线程并在一段时间后终止它?
【发布时间】:2011-12-12 16:03:12
【问题描述】:

交易是:

我想创建一个工作原理类似于在 Windows 中执行新 .exe 的线程,因此如果该程序(新线程)崩溃或进入无限循环:它将被优雅地终止(超过时间限制后或当它崩溃)并且所有资源都已正确释放。

当该线程成功时,我希望能够修改一些可能包含一些数据的全局变量,例如文件列表。这就是为什么我不能只从 Windows 执行外部可执行文件,因为我无法访问在新线程中执行的函数内部的变量。

编辑:进一步澄清了问题。

【问题讨论】:

  • WaitForSingleObject 不会终止线程。

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


【解决方案1】:

调用CreateThread后线程已经运行。

WaitForSingleObject 不是必需的(除非你真的想等待线程完成);但它不会“强制退出”线程;事实上,强制戒烟——即使有可能——从来都不是一个好主意;你可能会让资源保持打开状态或以其他方式使您的应用程序处于不好的状态。

【讨论】:

  • 哦,目的是在一段时间后退出线程,所以如果出现一些错误等,它不会一直运行。可以吗?
  • 你应该检查windows线程如何相互通信的信息;你可以例如使用信号做你想做的事。但是,如果出现了一些错误,而您只是终止了线程,则无法说线程是否没有做任何愚蠢的事情(例如,乱码应用程序内存),所以我想您不应该过分担心这些事情,除非您认为这是绝对必要的(我很难相信)。
  • 我明白了,我想它可能不会挂起,但我总是想到每一种失败的可能性。虽然此时我可以不进行终止检查,但我仍然不能 100% 确定没有失败的机会......你可以链接到那些所谓的信号,我可以在超过一段时间限制后使用它来终止线程?
  • 就是这样,这些事件(对不起,我的错误,它们被称为事件,而不是信号)可以用于仍然响应的线程相互通信(例如主线程和创建的线程),但它们不适合终止无响应的线程!
  • 没有其他方法可以安全地释放资源的新线程,有点像单击新的 .exe,当它崩溃时 Windows 也会自动释放资源? (我认为)
【解决方案2】:

线程不是某种可以用来做事的神奇对象。它是通过您的代码执行的单独路径。除非您专门对其进行编程,否则您的代码不能在其代码库中任意跳转。即便如此,也只能在 C++ 的规则内完成(即:调用函数)。

你不能杀死一个线程,因为杀死一个线程会彻底破坏程序员所做的一些最基本的假设。您现在必须考虑下一行未执行的可能性,因为您既无法预测也无法阻止。

这与异常处理不同,C++ 特别要求调用析构函数,并且您可以捕获异常并进行特​​殊清理。您正在谈论执行一段代码,然后突然结束整个调用堆栈的执行。那是行不通的。

Web 浏览器从“每个选项卡线程”模式转变为“每个选项卡进程”模型的原因正是这样:因为 进程 可以在不将其他进程留在一个未知状态。您需要的是使用进程而不是线程。

当进程完成并设置它的数据时,您需要使用一些进程间通信系统来读取该数据(我自己喜欢 Boost.Interprocess)。它看起来不像是一个常规的 C++ 全局变量,但阅读它应该没有问题。这样,如果进程耗时过长,您可以有效地终止进程,并且您的程序将保持在合理的状态。

【讨论】:

    【解决方案3】:

    嗯,这就是WaitForSingleObject 所做的。它一直阻塞,直到对象做某事(如果是线程,它会一直等到线程退出或超时)。你需要的是

    HANDLE thread = CreateThread(0, 0, do_stuff, NULL, 0, 0);
    //rest of code that will run paralelly with your new thread.
    WaitForSingleObject(thread, 4000); // wait 4 seconds or for the other thread to exit
    

    【讨论】:

    • 我明白了,是否有可能创建在一段时间后自动退出的线程,因此它不可能永远运行并占用我所有的 CPU 资源?
    • @Rookie。该线程本身应该负责。例如,它可以循环并在时间过去后退出循环
    • 是的,但是如果有一个错误导致该循环无休止呢?
    • 菜鸟:)调试一下,找到了:)
    • 确实,但是如果我在将程序发送给数百万人之前没有发现错误,并且他们都在非常严重的地方崩溃...相反,我更愿意告诉用户出了点问题,而不是让它崩溃并惹恼所有人。我不是上帝,所以我写不出完美的代码。
    【解决方案4】:

    如果您希望您的工作线程在经过一段时间后关闭,最好的方法是让线程本身以某种方式监控经过的时间,然后在时间到时退出。

    另一种方法是在主线程甚至第三个监控类型线程中监控经过的时间。当时间过去时,set an event。你的工作线程可以在它的主循环中wait for this event,然后在它被提升时退出。这类事件用于通知线程杀死自己,有时称为“死亡事件”。 (或者至少,我这么称呼他们。)

    另一种方法是queue a user job 到工作线程,它需要在alterable wait state 中。然后 APC 可以设置一些内部状态变量,当线程恢复时触发死亡序列。

    还有另一种方法,我什至不愿提及,因为它只应在极其恶劣的情况下使用。你可以kill the thread。这是一种非常危险的方法,类似于通过引爆原子弹来关闭水槽。你把水槽关掉了,但也可能有其他意想不到的后果。请不要这样做,除非您确切知道自己在做什么以及为什么这样做。

    【讨论】:

      【解决方案5】:

      删除对 WaitForSingleObject 的调用。这会导致您的父线程等待。

      【讨论】:

        【解决方案6】:

        删除WaitForSingleObject 调用?

        【讨论】:

          猜你喜欢
          • 2016-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-07-05
          • 2019-09-07
          相关资源
          最近更新 更多