2013-06-15 6 views
9

Angenommen, ich habe eine Bibliothek mit dieser Funktion gemeinsam genutzt, wobei "i" eine globale Variable ist.Wie sind globale Variablen in gemeinsam genutzten Bibliotheken verknüpft?

int foo() { 
return i++; 
} 

Wenn ich diese Funktion von mehreren Prozessen aus aufrufen, ist der Wert von "i" in jedem Prozess unabhängig von den anderen Prozessen.

Dieses Verhalten ist durchaus zu erwarten.

Ich frage mich nur, wie wird normalerweise dieses Verhalten vom Linker implementiert? Aus meiner Sicht wird der Code zwischen Prozessen geteilt, so dass die Variable in allen Adressräumen jedes Programms, das diese Bibliothek verwendet, dieselbe virtuelle Adresse haben muss. Dieser Zustand scheint mir ziemlich schwierig zu sein, daher denke ich, dass mir hier etwas fehlt und es anders gemacht wird.

Kann ich nähere Informationen zu diesem Thema erhalten?

+5

** Code ** ist freigegeben, nicht ** Daten. ** Der dynamische Linker erstellt vermutlich eine neue Kopie der Variablen für jeden Prozess, erstellt jedoch keine Kopien des Textsegments (Code). –

+0

@ H2CO3 Ich bin mir dessen bewusst. Ich frage jedoch nach den Einzelheiten des Verknüpfungsprozesses. –

+0

Nun, wenn Sie mehr Details benötigen, sollten Sie sich eine tatsächliche Implementierung ansehen. Der dynamische Linker in Linux und der in Darwin (BSD/OS X/iOS) sind Opensource. –

Antwort

0

Jeder Prozess hat seinen eigenen eindeutigen Adressraum. Wenn ein Prozess auf die Variable zugreift, kann er andere Werte haben als der andere Prozess. Wenn der Prozess den gleichen Speicher teilen sollte, müssten sie dies speziell einrichten. Eine gemeinsame Bibliothek ist nicht genug dafür.

+0

Ich bin mir der Sache bewusst, dass jeder Prozess eindeutigen Adressraum hat. Der Code ist jedoch freigegeben. und der Code bezieht sich auf eine Adresse (virtuell) im Speicher. Meine Frage ist, wie mit dem Ding umgegangen wird. –

+0

Auch wenn sie auf dieselbe Adresse verweisen, sind die Speicherseiten relativ zu ihrer Prozessumgebung. Die Speicherseiten werden vom Betriebssystem zugewiesen, so dass der Linker dafür nichts Besonderes tun muss. – Devolus

6

Der dynamische Verknüpfungsprozess zur Laufzeit (ähnlich wie der statische Verknüpfungsprozess) weist für jeden Prozess separate Datensegmente (und BSS-Segmente) zu und ordnet diese dem Prozessadressraum zu. Nur die Textsegmente werden zwischen Prozessen geteilt. Auf diese Weise erhält jeder Prozess eine eigene Kopie statischer Daten.

+0

Und ist es notwendig, die Datensegmente in jedem Adressraum genau an der gleichen Stelle zuzuordnen? Wenn ja, was passiert, wenn der Standort bereits von anderen Daten in einem der Bereiche verwendet wird? –

+0

Die Segmente werden zugewiesen, irgendwo dem Adressraum zugeordnet (was auch immer verfügbar ist), und dann wird ein Verbindungsprozess ausgeführt (Verschiebung usw. und Symbolauflösung). – Ziffusion

+0

Aber, wenn der Code geteilt wird, wie kann ich Umzug darauf durchführen, ohne andere Prozesse zu beeinflussen, die den gleichen Code verwenden? –

2

der Code zwischen Prozessen geteilt wird, so dass der Variable die gleiche virtuelle Adresse in allen Adressräumen jedes Programm, das diese Bibliothek

Der Code verwendet wird, nicht so, wie Sie geteilt denken. Ja, das dynamische freigegebene Objekt wird nur einmal geladen, aber die Speicherverweise oder der Stapel oder der Heap, die in dem so Code verwendet werden, werden nicht freigegeben. Nur der Abschnitt, der den Code enthält, wird freigegeben.

Verwandte Themen