2016-04-27 2 views
0

Ich habe eine Frage bezüglich einer gemeinsam genutzten Bibliothek, die von mehreren Prozessen verwendet wird.Erneutes Erstellen und Installieren der freigegebenen Bibliothek hat keinen Einfluss auf den Prozess, der diese Bibliothek bereits geladen hat

Ich habe eine gemeinsame Bibliothek libfoo.so, die von zwei verschiedenen Prozessen verwendet wird, process1 und process2.

Der erste Prozess (process1) befindet sich im Status "Running" und libfoo.so ist im Speicher geladen. Ich machte einige Änderungen in libfoo.so Code, umgebaut und installiert, dann begann process2. Die neue process2 hat die neu installierte Bibliothek libfoo.so geladen.

Aber process1 läuft noch mit älteren libfoo.so. Wenn ich process1 neu starte, lädt es die neu installierte libfoo.so wie erwartet.

Wenn das Betriebssystem eine einzige Kopie der gemeinsam genutzten Bibliothek hat, warum hat dann die Installation einer neuen gemeinsamen Bibliothek keinen Einfluss auf die derzeit laufenden Prozesse?

+0

Ich bin mir ziemlich sicher, dass die meisten, wenn nicht alle der .so zur Laufzeit in den Speicher geladen wird. – chrisd1100

+0

Was erwartest du? Warum? Definieren Sie, was Sie mit "Auswirkungen" meinen. – Olaf

+0

"Auswirkung" bedeutet, dass der Code der bereits geladenen Bibliotheksinstanz durch die geänderte Bibliothek oder die geänderte Bibliothek durch eine separate Instanz im Speicher ersetzt wird. –

Antwort

1

Wenn das Betriebssystem eine einzige Kopie der gemeinsam genutzten Bibliothek hat, warum hat dann die Installation einer neuen gemeinsamen Bibliothek keinen Einfluss auf die derzeit ausgeführten Prozesse?

Erstens ist Ihre gesamte Vorstellung einer einzelnen Kopie etwas fehlerhaft.

Lassen Sie uns über eine gemeinsam genutzte ELF-Bibliothek sprechen (die Konzepte gelten auch für andere Arten von Bibliotheken, obwohl die Details unterschiedlich sind).

Eine gemeinsam genutzte ELF-Bibliothek enthält normalerweise mindestens zwei ladbare Segmente: ein schreibgeschütztes und ein beschreibbares Segment. Die erste enthält schreibgeschützte Daten, Programmcode (oft als .text bezeichnet), Verschiebungsabschnitte usw. Das zweite Segment enthält initialisierte, aber schreibbare Daten (oft als .data bezeichnet).

Wenn zwei Prozesse ausführen und verwenden die gleichen libfoo.so, mindestens drei Speicherseiten durch libfoo.so verwendet wird: mindestens eine Seite zu „bedecken“, um das Nur-Lese-Segments (die Seite zwischen der geteilt werden zwei runing processes) und mindestens eine separate Seite in jeder Prozess, um das beschreibbare Segment zu "bedecken".

Wie Sie von diesem, eine einzige Kopie der gemeinsam genutzten Bibliothek auf dem Datenträger wird auch repliziert in mehrere Kopien in RAM während die Bibliothek von einem laufenden Programm verwendet wird, sehen können.

Zweitens müssen wir über wie Sie libfoo.so aktualisieren. Man konnte es in einer von zwei Möglichkeiten:

  1. Sie dies tun könnte: rm -f libfoo.so; gcc -shared -o libfoo.so foo.o oder
  2. Sie dies tun könnte: gcc -shared -o libfoo.so foo.o.

Im ersten Fall, werden Sie jeden Prozess nicht zu beeinflussen, die mmap ed hat libfoo.so überhaupt: die alten Daten für libfoo.so wird bleiben auf der Festplatte, sondern auf jeden Prozess nicht sichtbar, die sie noch nicht haben open ed oder mmap Ed. Beachten Sie außerdem, dass bei einer Größe von 1 GB die Plattennutzung um 1 GB zugenommen hat (alte und neue Kopien belegen immer noch Speicherplatz).

Im zweiten Fall aktualisieren Sie libfoo.soan Ort und Stelle (dies wird nicht empfohlen, aus Gründen, die in Kürze offensichtlich werden). Die Inode-Nummer für libfoo.so bleibt gleich, und die alten Daten sind verschwunden. Ihre Festplattenbelegung bleibt konstant (vorausgesetzt, dass die neue libfoo.so ungefähr so ​​groß ist wie die alte).

Diese wird beeinflussen jeden laufenden Prozess, aber vielleicht nicht in einer Weise, die Sie erwarten. Das wahrscheinlichste Ergebnis ist, dass Ihr laufender Prozess abstürzt.

Warum sollte es? Stellen Sie sich die Bibliothek als ein Buch vor, das ein Inhaltsverzeichnis enthält. Während des anfänglichen Ladens der Bibliothek wird das Inhaltsverzeichnis in den RAM geladen und geändert (weil die gemeinsam genutzte Bibliothek an einem beliebigen Ort im Speicher geladen werden kann). Wenn Sie nun das Buch (die Bibliothek auf der Platte) so aktualisieren, dass z. Kapitel 3 wird 3 Seiten länger, dann ist das Inhaltsverzeichnis nicht mehr gültig (zumindest für Kapitel 4 bis Ende). Wenn Sie versuchen, den Hinweisen im Inhaltsverzeichnis zu folgen, landen Sie nicht am Anfang des gesuchten Kapitels, sondern in der Mitte eines Kapitels. Sie würden also eine Funktion aufrufen und in der Mitte einer anderen Funktion landen. Das wahrscheinlichste Ergebnis ist ein Absturz. Das Bild ist noch komplizierter von demand paging. Vielleicht haben Sie in einigen Kapiteln etwas geblättert, andere jedoch nicht. So können Sie möglicherweise nicht entdecken, dass Ihr Prozess sofort nach dem Update abgespritzt wird. Wenn Ihre Bibliothek klein ist, können Sie diese überhaupt nicht entdecken.

P.S. Einige Betriebssysteme verbieten die zweite Form der Aktualisierung: Das Öffnen einer Bibliothek zum Schreiben schlägt mit ETXTBSY fehl, wenn die Bibliothek gerade von einem Prozess verwendet wird. Linux tut das für einige Dateisysteme, aber nicht für alle.

Verwandte Themen