【问题标题】:Restart application on unhandled exception在未处理的异常上重新启动应用程序
【发布时间】:2011-08-27 14:41:06
【问题描述】:

如果程序崩溃,是否可以自动重启?

类似:

  1. 引发未处理的异常。
  2. 释放进程分配的所有资源。
  3. 重新开始并调用 main。

我希望我正在处理的服务器应用程序具有这种行为。如果客户端错过了使用服务器,它可能会得到一个 std::bac_alloc 异常,在这种情况下,我希望服务器简单地重新启动而不是崩溃和关闭,从而避免手动启动。

【问题讨论】:

  • 修复服务器不是更好吗?
  • @forsvarir - 是的。但是,您并不总是有能力做到这一点。例如,早在 SETI@Home 客户端早期,我曾经为它做过类似的事情,因为它偶尔会无缘无故地死掉。如果我去度假什么的,我可能会暂时没有注意到,这会导致我严重落后于我的同事。不能这样!
  • @T.E.D.:说得好,老实说,我过去曾使用 shell 脚本来做类似的事情(作为安全网)。但在这种情况下,感觉可能有人知道问题出在哪里......但已经晚了,也许我读得太多了:)
  • @forsvarir,我在没有编写或没有源代码的过程中遇到了类似的情况。当它崩溃时,我对凌晨 2 点的电话感到恼火,所以我最后写了一个监控程序,在它消失后重新启动进程。不是一个完美的结果,但我睡得好多了!
  • @forsavir:Ofc。但是很难做到 100% 没有问题。

标签: c++ windows exception


【解决方案1】:

我之前在 Windows 中通过 win32 CreateProcess 调用从另一个程序运行所述程序来完成此操作。然后另一个程序等待“受监视”进程退出,如果退出,则再次调用其CreateProcess()。您可以通过在进程的句柄上执行WaitForSingleObject 来等待进程退出,这是您从CreateProcess() 调用中获得的返回值之一。

您当然会希望以某种方式进行编程,以使监控进程自行关闭并关闭其子进程。

【讨论】:

  • 松散地称为“看门狗”进程..这是 *nix 上非常常见的模式。如果您将应用程序编写为 Windows 服务,我很确定您可以配置服务管理器来为您重新启动进程。然后,您需要良好的日志记录(以及故障转储处理)来帮助诊断问题的根源。
  • 如果你的服务真的崩溃了,Windows 可以自动重启它。但如果它没有(例如,只是挂起),Windows 什么也不做。
  • “某种方式使监控进程自行关闭并关闭其子进程。”不要停在那里:)。
  • @ronag - 好吧,我停止了,因为这在很大程度上取决于您的监控过程是如何编写的,以及您希望它做什么。例如,作为 MFC 程序,您可以将该代码放在 OnExit 回调中。作为后台进程,您可能需要编写一个特殊的“关闭”程序来处理事件对象或其他东西。如果将其编写为 Windows 服务,则可以挂钩服务停止事件。
【解决方案2】:

让 Windows 成为您的看门狗。您可以致电ChangeServiceConfig2 为您的服务设置失败操作。 (如果您的服务器不是服务,那么您做错了。)为dwInfoLevel 参数指定SERVICE_CONFIG_FAILURE_ACTIONS,并在SERVICE_FAILURE_ACTIONS 结构中,将lpsaActions 设置为一个或多个@ 的数组987654323@ 值。你想要的类型是SC_ACTION_RESTART

【讨论】:

    【解决方案3】:

    我通过实现一个看门狗做了类似的事情。看门狗作为服务运行,并等待来自受监控进程的 ping(称为抚摸狗)。如果被监控的进程因异常而死掉,看门狗会清理并重新启动应用程序。

    如果应用程序没有响应(在特定时间内没有 ping),看门狗会杀死它然后重新启动它。

    这是您可能想要使用的实现的链接: http://www.codeproject.com/KB/security/WatchDog.aspx

    (PS:我实现了自己的版本,但我无法在此处发布。我是通过快速的 google 搜索找到的,并且对这个特定的实现没有第一手经验。)

    【讨论】:

      【解决方案4】:

      如果你只是捕获异常,应该可以通过内部编程逻辑重新启动服务器,而无需完全重新启动整个程序。

      【讨论】:

      • 如果您知道应用程序可以抛出的所有异常,这是正确的过程。
      • 你也可以捕获任何异常。
      • 一个 catch(...) {} 子句应该能够解决这个问题。不过,静态变量可能会很麻烦。
      • 这不会首先清理导致异常的混乱。最好完全退出并从头开始。
      • 好吧,我想 std::bad_alloc 意味着你的处境真的很糟糕。
      【解决方案5】:

      与@T.E.D. 一样,我们已经在我们构建的应用程序中完成了这项工作。我们的应用程序是一个 Windows 服务,因此帮助程序停止该服务(如果挂起,最终将其杀死)并重新启动该服务。

      【讨论】:

      • 是的,我的案例中也包含了一项服务。不怕小阿达的小伙伴可以去telepath.com/~dennison/Ted/SETI/SETI_Service.html查看源代码
      • 不错!我已经使用 SETI@Home 屏幕保护程序有一段时间了,但不幸的是还没有找到任何小绿人 :-)
      猜你喜欢
      • 1970-01-01
      • 2018-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-20
      • 2014-02-13
      • 2016-02-06
      • 1970-01-01
      相关资源
      最近更新 更多