【问题标题】:In C++, is it possible to detect the unexpected termination of a thread?在 C++ 中,是否可以检测到线程的意外终止?
【发布时间】:2018-02-16 18:53:03
【问题描述】:

我有一个不断处理数据的后台工作线程。
(使用std::thread 创建)

如果线程用完了要处理的数据,则线程被设计为等待 - 然后在 mote 数据可用于处理时恢复。
(使用std::condition_variable

如果此线程意外终止,我想确保线程以全新状态重新启动。

但我不知道如何检测线程终止或对其做出反应。
处理这种情况的最佳方法是什么?

【问题讨论】:

  • 你可以有一个at exit handler
  • 有办法检测吗?是的。您可以std::join 将阻塞直到它返回的线程(然后您可以重新创建它)。您可以密切关注当前进程存在哪些线程 ID,如果您的工作线程 ID 消失,您可以重新生成它。还有其他选择。基本上你的问题的答案是“是”。
  • 为什么会出乎意料?修复导致它终止的任何东西。
  • @MartinJames 这是一种预防措施,而不是错误修复。我试图将其设计为在不崩溃的情况下处理意外情况,而不是假设我可以预测可能发生的一切。
  • @JesperJuhl 谢谢。当然,加入线程是可行的——但它也违背了多线程的目的。我希望这个线程在后台继续处理,并且我不希望任何其他线程在不需要时等待它。观察线程 ID 是一个有趣的想法,我将不得不对此进行研究。 tadman 提到,使用thread_local 存储可能是最流畅的解决方案

标签: c++ multithreading exception exception-handling


【解决方案1】:

线程只能以受控方式退出:要么线程本身决定退出,要么被另一个线程取消。唯一的另一种可能性是您的程序崩溃或某些外部杀手事件。

如果您运行不同的进程而不是线程,情况会发生变化。在这种情况下是的,进程可能会意外退出,您需要弄清楚如何确定它是否存在。

如果您预计线程中的某些编码会导致意外退出,您可以只使用析构函数实例化一个保护类。后者可以做一些事情来通知你的系统线程存在:

 struct Watchdog {
     ~WatchDog() {
          restartMe();
     }
  };

  void start() {
     WatchDog watcher;
     ...
   }

您可能会尝试从析构函数中重新启动线程,或者只是通知另一个观察者线程您需要重新启动它。

当然,对于单独的进程,您需要一种完全不同的方法,即 heartbit ping 或其他方法。

【讨论】:

  • 这是我可能会使用的方法。看门狗对象也可能有thread_local 存储,这取决于我的需要。我还将线程执行的整个代码块包装在一个巨大的包中,因此任何未处理的异常都将导致干净的退出 + 重新启动。
  • @Giffyguy 'clean exit + restart' 与顶层的'while (true)' 循环有什么不同,围绕着你的'catch all'?
  • @MartinJames catch all 不会捕获线程的正常退出。即 pthread_exit
  • @MartinJames 我的代码包括一个while(true) 循环以及std::condition_variable,因此如果需要,后台线程可以暂停并等待更多数据进行处理。 try/catch-all 包含了整个循环,而不是相反。我不确定您认为这里发生了什么,但您似乎对这种情况感到不必要的困惑......
猜你喜欢
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 2021-06-08
  • 2019-06-06
  • 1970-01-01
  • 2012-04-29
  • 2015-02-11
  • 1970-01-01
相关资源
最近更新 更多