2013-06-15 9 views
9

"i"がグローバル変数であるこの関数で共有ライブラリがあるとします。共有ライブラリのグローバル変数はどのようにリンクされていますか?

int foo() { 
return i++; 
} 

私は複数のプロセスからこの関数を呼び出すと、各プロセスでの「i」の値が他のプロセスには無関係です。

この動作はかなり予想されます。

私はこの動作がリンカによってどのように実装されているのだろうかと疑問に思っていましたか?私の理解から、コードはプロセス間で共有されるので、変数はこのライブラリを使用するすべてのプログラムのすべてのアドレス空間に同じ仮想アドレスを持つ必要があります。その状態は私には達成するのが難しいようですので、私はここで何か不足していると思います。

このテーマに関する詳細情報はありますか?

+5

**コード**は**データではなく**共有されています**ダイナミックリンカーは、おそらく各プロセスの変数の新しいコピーを作成しますが、テキスト(コード)セグメントのコピーは作成しません。 –

+0

@ H2CO3私はそれをよく知っています。しかし、私はリンクのプロセスの詳細について尋ねています。 –

+0

詳細が必要な場合は、実際の実装を見てください。 Linuxの動的リンカーとDarwinのもの(BSD/OS X/iOS)はopensourceです。 –

答えて

0

各プロセスには固有のアドレス空間があります。したがって、プロセスが変数にアクセスすると、別の値と異なるプロセスを持つことができます。プロセスが同じメモリを共有する必要がある場合は、特にこれを設定する必要があります。共有ライブラリではそれでは不十分です。

+0

私は、各プロセスに固有のアドレス空間があることを認識しています。ただし、コードは共有されています。コードはメモリ内のいくつかのアドレス(仮想)を参照します。私の質問は、そのことがどのように処理されるかです。 –

+0

しかし、同じアドレスを指しているにもかかわらず、メモリページはプロセス環境に関連しています。メモリページはオペレーティングシステムによって割り当てられているため、リンカは特別な処理を行う必要はありません。 – Devolus

6

実行時のダイナミックリンク処理(静的リンク処理と同じ)は、各プロセスに別々のデータ(およびbss)セグメントを割り当て、それらをプロセスアドレス空間にマップします。テキストセグメントのみがプロセス間で共有されます。このようにして、各プロセスは独自の静的データのコピーを取得します。

+0

そして、すべてのアドレス空間でデータセグメントを正確に同じ場所に割り当てる必要がありますか?そうであれば、その場所がすでにスペースのいずれかの他のデータによって使用されている場合はどうなりますか? –

+0

セグメントは割り当てられ、アドレス空間に(使用可能なものは)どこにでもマッピングされ、実行される場合はリンク処理(再配置など)が割り当てられます。 – Ziffusion

+0

しかし、コードが共有されている場合、同じコードを使用する他のプロセスに影響を与えずに、どのように再配置を実行できますか? –

2

変数が

を使用するすべてのプログラムのすべてのアドレス空間内 同じ仮想アドレスにコードをこのライブラリを持たなければならないので、コードは、プロセス間で共有されては仕方あなたを共有していません思う。はい、動的共有オブジェクトは一度だけロードされますが、メモリ参照、またはsoでコードされているスタックまたはヒープは共有されません。コードを含むセクションのみが共有されます。

関連する問題