假设我有两个C ++函数foo1()和foo2(),我想最小化foo1()开始执行的可能性,但是由于某些外部事件而没有调用foo2()。如果两个都没有被调用,我不介意,但如果调用了foo1(),则必须执行foo2()。这两个函数都可以连续调用,不会抛出异常。
将函数包装在对象中并在析构函数中调用它们是否有任何好处/缺点?如果应用程序是多线程的(比如父线程崩溃)会发生什么变化?只要调用foo1(),还有其他选项可以确保调用foo2()吗?
我认为在析构函数中使用它们可能有助于例如SIGINT,虽然我知道SIGINT会立即停止执行,即使在析构函数的中间。
修改
澄清一下:foo1()和foo2()都会被抽象掉,所以我并不担心别人以错误的顺序调用它们。我的担心完全与应用程序执行过程中的崩溃,异常或其他中断有关(例如有人按SIGINT,另一个线程崩溃等)。
答案 0 :(得分:1)
如果另一个线程崩溃(没有相关的信号处理程序 - >整个应用程序退出),那么你无法保证你的应用程序能够做什么 - 它取决于操作系统的功能。并且总有一些情况下,系统会在没有您实际知识的情况下终止您的应用程序(例如,导致"所有"内存被您的应用程序和操作系统使用的内存"内存杀手"杀死你的过程)。
保证析构函数执行的唯一时间是构造对象并抛出C ++异常。所有信号等都没有做出这样的保证,并且继续执行[在同一个线程中]例如SIGSEGV或SIGBUS之后很好地进入" undefined"世界各地 - 你无能为力,因为SEGV通常意味着"你试图做一些不存在的记忆[或你不能以你的方式访问试过,例如写入代码存储器",处理器将中止当前指令。试图继续你所处的位置将导致再次执行相同的指令,或者跳过指令[如果继续下一条指令 - 我忽略了确定现在的位置的麻烦]。当然,有些情况下,即使您想要继续它也是不可能的 - 例如,堆栈指针已被损坏[从被覆盖的内存中恢复等]。
简而言之,不要花很多时间试图想出一些试图避免这种情况的东西,因为它不太可能奏效。花点时间尝试提出你不需要知道是否完成某些事情的方案[例如基于交易的编程,或者基于提交的"编程(不确定这是否是正确的术语,但基本上你做了一些步骤,然后"提交"到目前为止完成的事情,然后做一些进一步的步骤等 - 只有那些有的东西已经"承诺"肯定是完整的,未提交的工作在下次被丢弃),其中某些事情要么完全完成,要么完全丢弃,这取决于它是否已经完成]。
分离"敏感"并且"不敏感"将应用程序的一部分分成不同的进程可以是另一种实现更高安全性的方法。