1

ユーザー定義のロジックを適用できるようにするために、プログラムへの一種のプラグインとして .so を使用しています。プログラムの複数のインスタンスが実行され、それぞれがプログラムのそのインスタンスのユーザー固有のロジックを定義する固有の .so を持ちます。プログラムは無期限に実行されるのが理想的ですが、ロジックの一部を変更する必要がある場合もあるため、.so がいつ変更されたかを検出し、新しい .so をアップロードするという素晴らしいアイデアがありました。そうすれば、プログラムを強制終了/再起動せずに特定の実装ロジックを変更できます (データが失われる可能性があります)。

loadPlugin 関数が機能しており、inotify を使用して .so がいつ変更されたかを検出し、再度ロードしています。これは計画どおりに機能しませんでした。すべての .so がメモリにロードされ、その時点から物理ファイルから完全に独立していると想定していましたが、明らかにそうではありません。警告せずに .so ファイルを変更すると、プログラムが segfault でクラッシュします。.so を rm してから新しいバージョンをコピーすると、プログラムはクラッシュしません。削除されたプラグインのバージョンをメモリに保持することを知っていると言われます。ただし、loadPlugin メソッドが起動して新しく変更された .so をロードしようとすると、古いものへの参照が返されるだけです。新しいメソッドではなく .so メソッド。それらが同一であると想定しているため、デフォルトでメモリに既にロードされているバージョンを使用すると想定していますが、特に新しいバージョンをロードする必要があります! その .so を使用するアプリケーションは 1 つだけなので、.so の定義を上書きしても安全です。それを実現する方法を知っていれば。

これらの問題を回避する最善の方法は何だろうか。私の最初のアイデアは、ロードする前に.soファイルのバージョンを別の場所にコピーして、元のファイルが変更されてもプログラムがクラッシュしないようにすることですが、それは主な問題を回避しません. inotify がメモリに持っている .so ファイルのキャッシュされたバージョンを無視し、新しいバージョンのプラグインをロードするように inotify に指示するにはどうすればよいですか? plugin1.so の実行中に plugin2.so を変更してロードし、plugin1.so を解放して変更できるように、2 つの別個のファイル (plugin1.so、plugin2.so) を交互に切り替える必要がありますか? これでも機能しますか、それとも両方のバージョンを 1 回読んだ後に「キャッシュ」されてしまい、3 回目に変更されたプラグインをロードできなくなりますか?

ps。ご想像のとおりですが、私は Linux (具体的には redhat または centos) で C++ を使用しています。最終的なランタイム環境で OS を定義できるので、移植性は常に優れていますが、唯一のメソッドが移植可能でない場合は必要ありません。

4

2 に答える 2

1

プラグインを更新するときに、プラグインに別の SONAME を設定しようとしましたか? SONAME は、同じライブラリの異なるバージョンを区別するものであり、これはほとんどあなたが求めているものです。

あなたのマシンの /usr/lib または /lib を調べて、そこに作成されたシンボリックリンクを誰が定義したのか疑問に思うなら、それは個々のライブラリの SONAMES です ;-)

man ldまたはman gcc、リンク時に SONAME を指定する方法を教えてください。

于 2012-08-07T15:49:44.303 に答える
1

ダニが指摘したように、問題は私の dlclose 呼び出しにありました。間違ったヘッダーを渡し、DL を適切に閉じていませんでした。新しいメソッドを適切にロードできることを修正するとすぐに。ファイルを変更してプログラムを強制終了させるという問題はまだありますが、必要に応じて回避できることはわかっています。

于 2012-08-07T21:19:36.287 に答える