2.3 Speicherbereiche eines Prozesses

Beim Laden einer dynamischen Bibliothek werden die nichtkonstanten Datenbereiche (initialisierte Daten beispielsweise im .data-Segment; nicht initialisierte im .bss-Segment) der Bibliothek den entsprechenden Bereichen des aufrufenden Prozesses angegliedert; (nicht konstante) globale Variablen sind also so oft vorhanden wie die Bibliothek gerade verwendet wird: im Adreßbereich jedes Aufrufers einmal. Dies kann man an den Beispielprogrammen gut sehen, wenn man gleichzeitig mehrere Programme startet: die globale Variable Wert, deren Inhalt als Rückgabewert von immereinsmehr() (jeweils um eins erhöht) verwendet wird, beginnt auch bei mehreren Instanzen für jeden Prozeß neu zu zählen.

Konstante globale Daten (also beispielsweise das .rodata Segment) werden vom Betriebssystem ähnlich wie der Maschinencode nur einmal für alle Prozesse im realen Speicher angelegt, und in alle beteiligten Prozesse eingeblendet (allerdings gleichzeitig über die memory management unit (MMU) vor einem Beschreiben durch die Prozesse geschützt).

Als Stackspeicher nutzt jede Instanz einer dynamischen Bibliothek den Stack des aufrufenden Prozesses; anders könnte man ja auch gar keine Werte an die Funktionen der Bibliothek übergeben.

Beim Absturz eines der Prozesse wird dessen Speicher wie üblich freigegeben, und die Bibliothek verbleibt im Speicher zumindest bis der letzte nutzende Prozeß beendet ist.

Durch diese Maßnahmen erscheint jede Instanz einer dynamischen Bibliothek für den Aufrufer so, als ob er der einzige Nutzer der Bibliothek wäre. Erklärtes Ziel ist die saubere Trennung der Prozesse.

Insbesondere ist es nicht möglich, daß Prozesse über eine dynamische Bibliothek Daten austauschen (in der Art: ein Prozeß beschreibt eine Variable, ein anderer liest den geänderten Wert). Zur Kommunikation zwischen Prozessen sind also andere Mechanismen nötig.

Tip Linux: Wenn die globalen Symbole eines aufrufenden Programms verwendet werden sollen, um die Referenzen im shared object aufzulösen, dann muß beim Linken des Aufrufers die Option -rdynamic angegeben werden. Ansonsten sieht die Bibliothek die globalen Symbole des Aufrufers nicht, was auch erwünscht sein kann. Siehe man 3 dlopen.

Unter Windows hat man diese Wahlmöglichkeit nicht; hier sind die globalen Symbole des Aufrufers immer für die DLL sichtbar.

Gegebenenfalls kann man die Sichtbarkeit von globalen Objekten mit static steuern; siehe [KW: C].

www.wachtler.de