2013-06-15 18 views
9

Załóżmy, że mam wspólną bibliotekę z tą funkcją, gdzie "i" jest jakąś zmienną globalną.W jaki sposób powiązane są zmienne globalne w bibliotekach wspólnych?

int foo() { 
return i++; 
} 

Kiedy wywołać tę funkcję od wielu procesach wartość „i” w każdym procesie jest niezależny od innych procesów.

To zachowanie jest dość spodziewane.

Zastanawiam się, jak zwykle to zachowanie jest realizowane przez linker? Z mojego rozumienia kod jest dzielony między procesy, więc zmienna musi mieć ten sam adres wirtualny we wszystkich przestrzeniach adresowych każdego programu, który używa tej biblioteki. Ten stan wydaje się dość trudny do osiągnięcia, więc myślę, że tu coś pomijam i robi się to inaczej.

Czy mogę uzyskać bardziej szczegółowe informacje na ten temat?

+5

** Kod ** jest udostępniony, a nie ** dane. ** Dynamiczny linker prawdopodobnie tworzy nową kopię zmiennej dla każdego procesu, ale nie tworzy kopii segmentu tekstowego (kodu). –

+0

@ H2CO3 Jestem tego świadomy. Jednak pytam o szczegóły procesu łączenia. –

+0

Cóż, jeśli potrzebujesz więcej szczegółów, myślę, że powinieneś rzucić okiem na rzeczywistą implementację. Dynamiczny linker w Linuksie i ten w Darwin (BSD/OS X/iOS) to opensource. –

Odpowiedz

0

Każdy proces ma własną unikalną przestrzeń adresową, więc gdy proces uzyskuje dostęp do zmiennej, może mieć różne wartości, a następnie inny proces. Jeśli proces powinien współdzielić tę samą pamięć, musieliby to ustawić. Wspólna biblioteka to za mało.

+0

Jestem świadomy tego, że każdy proces ma unikalną przestrzeń adresową. Jednak kod jest udostępniany. a kod odnosi się do jakiegoś adresu (wirtualnego) w pamięci. Moje pytanie dotyczy tego, jak to się dzieje. –

+0

Mimo że wskazują one na ten sam adres, strony pamięci są powiązane z ich środowiskiem procesowym. Strony pamięci są przypisywane przez system operacyjny, więc linker nie musi robić nic specjalnego. – Devolus

6

Dynamiczny proces łączenia w czasie wykonywania (bardzo podobny do procesu łączenia statycznego), przydziela oddzielne segmenty danych (i bss) dla każdego procesu i odwzorowuje je w przestrzeni adresowej procesu. Tylko segmenty tekstu są współużytkowane między procesami. W ten sposób każdy proces otrzymuje własną kopię danych statycznych.

+0

Czy konieczne jest przydzielenie segmentów danych do dokładnie tej samej lokalizacji w każdej przestrzeni adresowej? Jeśli tak, co się stanie, jeśli lokalizacja jest już używana przez inne dane w jednym ze spacerów? –

+0

Segmenty są przydzielane, mapowane gdzieś w przestrzeni adresowej (wszystko, co jest dostępne), a następnie proces łączenia, jeśli jest wykonywany (przeniesienie itp. I rozdzielczość symbolu). – Ziffusion

+0

Ale jeśli kod jest udostępniony, w jaki sposób mogę przeprowadzić na nim relokację bez wpływu na inne procesy korzystające z tego samego kodu? –

2

kod jest dzielone pomiędzy procesami, więc zmienna musi mieć sam adres wirtualny we wszystkich przestrzeniach adresowych każdego programu, który używa tej biblioteki

Kod nie jest dzielona sposób myśleć. Tak, dynamiczny obiekt współdzielony jest ładowany tylko raz, ale odwołania do pamięci lub stos lub sterty, które kodują w zastosowaniach so, nie są udostępniane. Udostępniana jest tylko sekcja zawierająca kod.

Powiązane problemy