制作过程在其线程中存在失败

时间:2013-07-15 23:01:19

标签: c linux unix posix

我正在编写具有许多独立线程的应用程序。虽然我在那里做了很低级别,危险的东西,线程可能会失败(SIGSEGV,SIGBUS,SIGFPE),但它们不应该杀死整个过程。有没有办法正确地做到这一点?

目前我拦截上述信号并在其信号处理程序中然后调用pthread_exit(NULL)。它似乎工作,但由于pthread_exit不是异步信号安全功能,我有点担心这个解决方案。

我知道将此应用程序拆分为多个流程可以解决问题,但在这种情况下,这不是一个可行的选择。

编辑:由于忽略了SIGSEGV / SIGBUS / SIGFPE,我知道可能发生的所有Bad Things™(我在低级系统和内核编程方面经验丰富),所以请尝试回答我的特定问题而不是给我关于可靠性的课程。

2 个答案:

答案 0 :(得分:1)

执行此操作的正确方法是让整个过程死亡,然后启动另一个过程。你没有解释为什么这不合适,但从本质上讲,这是完全安全的唯一方法来对付各种令人讨厌的角落情况(在你的情况下可能适用也可能不适用)。

我不知道任何100%安全的方法,不涉及让整个过程。 (另请注意,有时只是从这些错误中继续行为的行为是“未定义的行为” - 这并不意味着你肯定会摔倒,只是它可能是一个问题)。

当然有可能有人知道一些有效的巧妙技巧,但我很确定唯一100%保证的方法是杀死整个过程。

答案 1 :(得分:1)

低延迟代码设计需要小心“了解您运行的系统”类型的编码部署。这意味着,例如,标准 IPC机制(例如,使用SysV msgsnd / msgget在进程之间传递消息,或pthread_cond_wait / {{1}在PThreads方面)以及普通锁定原语(自适应互斥锁)被认为是相当慢的......因为它们涉及需要数千个CPU周期的东西......即上下文切换。

相反,使用“热 - 热”切换机制,例如破坏者模式 - 生产者以及消费者旋转在紧密循环中永久轮询单个或最坏的少数原子更新存储位置,表示找到下一个待处理项目的位置和/或标记已处理的项目完成。将所有生产者/消费者绑定到单独的CPU核心,以便他们永远上下文切换。

在这种类型的用例中,您是使用单独的线程(并通过共享相同地址空间的所有线程隐式获取内存)或单独的进程(并通过以下方式获取内存共享 使用共享内存进行数据处理以及队列管理“元数据”)几乎没有什么区别,因为TLB和数据缓存“总是很热”(你从不上下文切换)。

如果你的“处理器”不稳定和/或没有保证完成时间,你需要添加一个“收割机”机制来处理失败/超时消息,但这种垃圾收集机制必然会引入抖动(延迟峰值) 。那是因为你需要一个系统调用来确定一个特定的线程或进程是否已经退出,即使在最好的情况下,系统调用延迟也只有几个。

从我的观点来看,你在这里尝试混合油和水;您需要使用未专门编写的库代码用于不受您控制的低延迟部署/库代码,并结合使用nanosec延迟进行消息调度的要求。 无法制作,例如pthread_cond_signal为您提供nsec延迟,因为必须执行系统调用才能唤醒目标,这需要更长时间。

如果你的“处理程序代码”依赖于“丰富”的环境,并且这些与主程序之间共享了大量的“状态”...这听起来有点像说“我需要制作一个蒸汽 - 驱动飞机打破音障“......