2012-04-05 5 views
3

Diese Frage bezieht sich hauptsächlich auf gemeinsam genutzte Bibliotheken (.so-Dateien), die für Linux-Plattformen kompiliert wurden. Wird die neue Bibliotheksdatei beim nächsten Start eines davon abhängigen Programms automatisch geladen? Wenn nicht, gibt es einen anderen Weg, um diese stille, in sich geschlossene Bibliothek zu aktualisieren?Kann eine C/C++ - Linux-Shared-Library automatisch aktualisiert werden, indem ihre eigene Datei auf dem Datenträger in eine neuere Version überschrieben wird?

+0

einige der Antworten auf meine [Frage] [1] [1] Siehe: http://stackoverflow.com/questions/10001013/update-shared-libraries-without-restarting-processes – Manohar

Antwort

6

Viele Unix-basierte OS haben Dateisysteme, die diese Art von Sachen zulässt, wenn Sie die gleiche Datei entfernen und dann neu erstellen. Soweit Vlad Lazarenko und ich wissen, Windows & DOS sind das einzige Betriebssystem, das kann das nicht tun.

Solange eine Datei geöffnet ist, wird sie so lange aufbewahrt, bis nichts mehr benötigt wird. Wenn Sie es entfernen, ist es in den fs nicht sichtbar, aber es ist immer noch vorhanden. Es funktioniert für alle Arten von Dateien.

Aber Sie werden wahrscheinlich Stammrechte benötigen, um dies in einer Bibliothek zu tun. Und Sie sollten auf Synchronisation und Abhängigkeiten zwischen mehreren Bibliotheken achten. Sie können h schnell in eine Situation bringen, in der liba v1.0 nur mit libb v1.0 arbeiten kann und wenn Sie liba automatisch aktualisieren, wird es fehlschlagen.

Es gibt mindestens zwei bekannte Programme, die diese Technik verwenden: apt und rpm.

BEARBEITEN: Es gibt wirklich kein Problem, wenn Sie Ihre Bibliothek nach dem Entfernen/Neu erstellen Muster aktualisieren. Ihre alte, aber in Benutzung befindliche Bibliothek ist sowohl im Speicher als auch auf der Festplatte vorhanden. Ihr Betriebssystem kann bei Bedarf einen Teil Ihrer Bibliothek auf dem Datenträger neu laden.

Ihre Bibliothek ist noch auf der Festplatte, solange alle das Programm, das es verwendet, geschlossen sind. Das ist sogar für libc der Fall. Deshalb werden Sie, wenn Sie Ihre libc aktualisieren, aufgefordert, fast alle Dienste, die sie benutzen, neu zu starten, um sie auf den neuen Binärcode zu aktualisieren.

Und das ist auch der Hauptgrund, warum Sie ein Linux-System aktualisieren können, ohne es seit Jahren neu zu starten.

+2

Es ist nicht nur Linux, es ist im Grunde Betriebssystem außer einem gebrochenen MS-DOS alias Windows. –

+0

Danke für die Antwort. Könnte es als eine Folgefrage einen möglichen Absturz in dem Programm verursachen, das die alte Bibliothek ausführt, nachdem die Datei auf der Platte aktualisiert wurde? Ist es möglich, dass das Betriebssystem einen Teil der Bibliothek im Speicher auslagert und dann versucht, diese Seiten später von der Festplatte neu zu laden? – Karthik

+1

@VladLazarenko Ich stimme dir zu, so habe ich meine Antwort entsprechend aktualisiert :). – Coren

0

Sie haben einige ausgezeichnete Antworten erhalten (besonders Coreens), also dachte ich, ich würde eine Frage stellen. Willst du das wirklich tun? Sofern Sie keine Fehler beheben und die Funktionssignaturen nicht ändern, ist es vielleicht besser, die Versionsnummer zu ändern und eine neue Version zu implementieren, oder?

+0

Nein, das möchte ich nicht: P Aber es ist eine Situation, in der die Bereitstellung einer neuen Version über einen herkömmlichen Kanal Monate dauern kann ... und die Änderungen werden garantiert keine vertraglich definierten Schnittstellen unterbrechen. Im Grunde eine Möglichkeit, unsere eigenen Esel zu retten, wenn etwas Kritisches bricht, kann einen Hotfix schieben. – Karthik

3

Wenn unter Linux, mit einem guten Linux-Dateisystem (zB ext3 oder ext4 oder Btrfs), können Sie eine gemeinsame Bibliothek aktualisieren könnten (zB libfoo.so) innerhalb eines Prozesses und Programm (zB bar) unter Verwendung es (zB dlopen -ing, dass libfoo.so)

Sie werden vorzugsweise

  1. zu rename(2) haben die alte libfoo.so zum Beispiel libfoo-old.so
  2. -dlopen(3) die neue Version von libfoo.so
  3. -dlsym, was Sie wollen in er
  4. zu vielleicht dlclose(3) der alten dlopen -ed Griff auf die alte Version; Das geht nur, wenn kein aktiver Rufrahmen auf libfoo-old.so zeigt (sonst stürzt Ihr Programm bei der Rückkehr in solche Rufrahmen ab).
  5. unlink(2) die libfoo-old.so wenn

benötigt (Sie rename vermeiden konnte und man konnte sogar unlink eine aktive dlopen -ed Bibliothek, der Kernel wäre es, wenn keine weiteren Verzeichniseintrag oder Prozess Dateideskriptors Punkte, um es zu entfernen; Ich werde das nicht empfehlen, zB um das Debugging von potentiellen core Dumps zu erleichtern.

Eine einfachere, aber "undichte" Alternative ist nie dlclose. In der Praxis kann ein Programm dlopen viele Dutzend Tausende *.so ohne Angst. Siehe mein altes manydl.c Beispiel.

+0

Hmm, das erfordert, dass das Programm das Update richtig kennt? Ich möchte eine viel günstigere Lösung: Die Bibliothek prüft, ob es eine neuere Version gibt, lädt sie herunter und schreibt sich neu. – Karthik

+0

Es kann die Bibliothek selbst sein. Aber ich glaube nicht, dass es sich bei jedem Auftreten von laufenden Prozessen, die diese Bibliothek verwenden, ersetzen kann. Die Ersetzung wäre nur für die nächste Ausführung der Programme wirksam. –