隔离容易崩溃的 (SEGV) 但将关键的遗留代码加速到单独的二进制文件中
Isolate crash prone (SEGV) but speed critical legacy code into a separate binary
我有一个经过良好测试且没有崩溃的代码库(主要是 C++)。大多。代码的一部分——不可替代、难以维护或改进并链接到一个二进制库*——导致所有崩溃。这些不会经常发生,但一旦发生,整个程序就会崩溃。
+----------------------+
| Shiny new sane |
| code base |
| |
| +-----------------+ | If the legacy code crashes,
| | | | the entire program does, too.
| | Legacy Code | |
| | * Crash prone * | |
| | int abc(data) | |
| +-----------------+ |
| |
+----------------------+
是否可以将那部分代码提取到单独的程序中,从主程序启动,在这些程序之间移动数据(在 Linux、OS X 上,如果可能,Windows),容忍子进程崩溃并重新启动子进程?像这样:
+----------------+ // start,
| Shiny new sane | ------. // re-start on crash
| code base | | // and
| | v // input data
| | +-----------------+
| return | | |
| results <-------- | Legacy Code |
+----------------+ | * Crash prone * |
| int abc(data) |
(or not results +-----------------+
because abc crashed)
理想情况下,通信速度足够快,以便可以用包装器透明地替换对 int abc(char *data)
的同步调用(假设非崩溃情况)。并且由于轻微的内存泄漏,遗留程序应该每隔一小时左右重新启动一次。崩溃是确定性的,因此错误的输入数据不应发送两次。
代码库是 C++11 和 C,著名的外部库是 Qt 和 boost。它在 Linux、OSX 和 Windows.
上运行
--
*: 一些 crashes/leaks 来自这个没有可用源代码的库。
嗯,如果我是你,我不会从这里开始......
然而,你就是你所在的地方。是的,你可以做到。您将必须序列化您的输入参数,发送它们,在子进程中反序列化它们,运行 函数,序列化输出,return 它们,然后反序列化它们。 Boost 将有很多有用的代码来帮助解决这个问题(参见 asio)。
全局变量会让生活更精彩"interesting"。遗留代码是否使用 Qt? - 这可能不喜欢被分成两个进程。
如果您只使用 Windows,我会说 "use DCOM" - 这让事情变得非常简单。
如果仅从一个线程使用旧版(处理 "return" 的代码只是查看是否需要重新启动,然后终止进程。),那么重新启动就足够简单了。如果您有多个线程,然后闪亮的代码将需要检查是否需要重新启动,阻止任何进一步的线程,等到所有调用都已 returned,重新启动进程,然后取消阻止所有内容。
Boost::interprocess 看起来拥有通信所需的一切 - 它具有共享内存、互斥锁和条件变量。 Boost::serialization 将完成编组和解组工作。
我有一个经过良好测试且没有崩溃的代码库(主要是 C++)。大多。代码的一部分——不可替代、难以维护或改进并链接到一个二进制库*——导致所有崩溃。这些不会经常发生,但一旦发生,整个程序就会崩溃。
+----------------------+
| Shiny new sane |
| code base |
| |
| +-----------------+ | If the legacy code crashes,
| | | | the entire program does, too.
| | Legacy Code | |
| | * Crash prone * | |
| | int abc(data) | |
| +-----------------+ |
| |
+----------------------+
是否可以将那部分代码提取到单独的程序中,从主程序启动,在这些程序之间移动数据(在 Linux、OS X 上,如果可能,Windows),容忍子进程崩溃并重新启动子进程?像这样:
+----------------+ // start,
| Shiny new sane | ------. // re-start on crash
| code base | | // and
| | v // input data
| | +-----------------+
| return | | |
| results <-------- | Legacy Code |
+----------------+ | * Crash prone * |
| int abc(data) |
(or not results +-----------------+
because abc crashed)
理想情况下,通信速度足够快,以便可以用包装器透明地替换对 int abc(char *data)
的同步调用(假设非崩溃情况)。并且由于轻微的内存泄漏,遗留程序应该每隔一小时左右重新启动一次。崩溃是确定性的,因此错误的输入数据不应发送两次。
代码库是 C++11 和 C,著名的外部库是 Qt 和 boost。它在 Linux、OSX 和 Windows.
上运行--
*: 一些 crashes/leaks 来自这个没有可用源代码的库。
嗯,如果我是你,我不会从这里开始......
然而,你就是你所在的地方。是的,你可以做到。您将必须序列化您的输入参数,发送它们,在子进程中反序列化它们,运行 函数,序列化输出,return 它们,然后反序列化它们。 Boost 将有很多有用的代码来帮助解决这个问题(参见 asio)。
全局变量会让生活更精彩"interesting"。遗留代码是否使用 Qt? - 这可能不喜欢被分成两个进程。
如果您只使用 Windows,我会说 "use DCOM" - 这让事情变得非常简单。
如果仅从一个线程使用旧版(处理 "return" 的代码只是查看是否需要重新启动,然后终止进程。),那么重新启动就足够简单了。如果您有多个线程,然后闪亮的代码将需要检查是否需要重新启动,阻止任何进一步的线程,等到所有调用都已 returned,重新启动进程,然后取消阻止所有内容。
Boost::interprocess 看起来拥有通信所需的一切 - 它具有共享内存、互斥锁和条件变量。 Boost::serialization 将完成编组和解组工作。