1

我在我的程序中使用 .so 作为一种插件,以允许应用用户定义的逻辑。该程序的多个实例将运行,每个实例都有自己特定的 .so 定义该程序实例的用户特定逻辑。理想情况下,该程序将无限期运行,但有时需要更改某些逻辑,因此我有一个聪明的想法,即检测 .so 何时被修改并上传新的 .so。这样就可以在不终止/重新启动程序的情况下更改特定的实现逻辑(这可能导致数据丢失)。

我有 loadPlugin 函数工作,我正在使用 inotify 来检测 .so 何时更改并再次加载它。这没有按计划进行。我曾假设所有 .so 都加载到内存中,并且从那时起完全独立于物理文件,但显然情况并非如此。如果我在没有警告的情况下更改 .so 文件,我的程序会因段错误而崩溃。如果我 rm .so 然后复制一个新版本,程序不会崩溃 - 我被告知它知道在删除插件时将其保留在内存中。但是,当我的 loadPlugin 方法开始尝试加载新修改的 .so 时,它只会返回对旧的引用.so 方法而不是新方法。我假设它默认使用已加载到内存中的版本,因为它假设它们是相同的,但我特别希望它加载新版本!由于只有一个应用程序会使用该 .so,而且我确信在我加载新的 .so 时它不会调用 .so 的方法,因此覆盖 .so 的定义是安全的如果我知道如何做到这一点。

我想知道解决这些问题的最佳方法是什么?我的第一个想法是在加载之前将 .so 文件的一个版本复制到另一个位置,这样即使修改了原始文件,我的程序也不会崩溃,但这并不能解决主要问题。我如何告诉 inotify 忽略它在内存中的任何缓存版本的 .so 文件并加载新版本的插件?我是否需要在两个单独的文件(plugin1.so、plugin2.so)之间交替,以便在 plugin1.so 运行时我可以修改 plugin2.so 并加载它,从而释放 plugin1.so 以进行更改?这是否可行,或者我是否会在阅读一次后将两个版本都“缓存”,并且在第三次更改插件时无法加载插件?

附言。我相信你猜到了,但我在 linux 上使用 C++(特别是 redhat 或 centos)。我可以在最终的运行时环境中定义我的操作系统,所以虽然可移植性总是很好,但如果唯一的方法不可移植,我就不需要它。

4

2 回答 2

1

您是否尝试在更新插件时为插件设置不同的 SONAME?SONAME 是区分同一库的不同版本的区别,这几乎就是您所要求的。

如果您查看机器上的 /usr/lib 或 /lib 并想知道是谁定义了在那里创建的符号链接,那是各个库的 SONAMES ;-)

man ld或者man gcc应该告诉您如何在链接时指定 SONAME。

于 2012-08-07T15:49:44.303 回答
1

正如 Dani 指出的那样,问题出在我的 dlclose 电话中。我传入了错误的标题并且没有正确关闭 DL。一旦我修复了我可以正确加载新方法的问题。对文件的更改仍然会导致程序终止,但我知道如果需要我可以解决这个问题。

于 2012-08-07T21:19:36.287 回答