捕获信号c ++

时间:2011-12-21 16:34:42

标签: c++ threadpool signals handle

我有一个提升线程池,用于执行某些任务。我还有一个具有纯虚函数doWork(int total) = 0;的Sensor类。每当请求时,我的主进程都会获取必要的Sensor指针并告诉线程池运行Sensor::doWork(int total)

threadpool->schedule(boost::bind(&Sensor::doWork,this,123456));

我正在动态加载Sensor类型的库,因此如果其他人的编码错误导致SEGFAULTS等,则我无法控制。那么有没有办法(在我的主进程中)处理Sensor::doWork(int total)引发的任何错误,清理线程,删除该传感器对象并通知控制台错误发生的位置和位置?

3 个答案:

答案 0 :(得分:2)

此处处理细分错误的唯一方法是在完全独立的进程中运行Sensor::doWork

在UNIX中,这涉及使用fork(或其他类似方法),在子进程中运行Sensor::doWork,然后以某种方式将结果切换回父进程。

我假设Windows中有类似的方法。

编辑:我以为我会充实一些你可以做的事情。

解决方案#1:您可以使用与线程相同的方式处理进程。例如,您可以创建位于

循环中的进程池
  • 等待通过管道或队列或类似对象传递任务
  • 执行任务
  • 通过管道或队列或类似对象返回结果

由于您在其他进程中执行任务,因此可以防止它们崩溃。该解决方案的主要困难实际上是在进程之间进行通信;也许boost的进程间库可以帮助你。我主要在python中做过这种事情,它有一个标准的multiprocessing模块,可以为你处理这些东西。

解决方案#2:您可以将应用程序划分为在不同进程中运行的“安全”和“风险”部分。 “冒险”部分执行Sensor::doWork方法以及您在该过程中可能想要做的任何其他事情 - 但只有在崩溃时可以自发丢失的工作。 “安全”部分处理您不能丢失的任何珍贵信息,并监控“风险”部分,在儿童崩溃时执行一些恢复操作。当然,无论你决定在安全部分做什么其他工作。

答案 1 :(得分:1)

如果你有一个SIGSEGV,即使你发现了它,也无法保证你的程序状态,所以几乎无法恢复。

如果您正在使用第三方库,并且他们有错误,并且图书馆维护人员无法修复它(并且您没有源代码)那么您唯一的办法是运行第三方库在完全独立的二进制文件中,通过某种方式与主二进制文件进行对话请参阅firefox和plugin-container。

答案 2 :(得分:0)

您可能希望注册函数回调以捕获SIGSEV。在C中,这可以使用signal来完成。但请注意,当操作系统向您发送SIGSEV时(注意不需要),您无能为力。我猜,你真的不知道你的节目处于什么状态。例如,如果堆已损坏,则new和delete操作可能会失败,因此即使是简单的

 std::cout << std::string("hello world") << std::endl; 

语句可能不起作用,因为需要分配来自堆的内存。

Best,Christoph