6

私は共有ライブラリがどのように機能するかをよりよく理解しようとしてきましたが、2 つのことについて頭を悩ますことができません。

1-各プロセスには独自の仮想メモリ空​​間とページテーブルがあるため、共有ライブラリが1つのプロセス仮想メモリ空​​間にロードされた場合、2番目のプロセスはメモリ空間にないため、どのようにしてその共有ライブラリにアクセスできますか?

2- テキスト セクションのみが共有され、グローバル データは共有されないことを理解しています。これはどのように可能ですか? 私の理解では、グローバル変数への各参照はグローバル オフセット テーブル(略して GOT) を介して行われます。したがって、このコード行がある場合、これは、GOT のベース値として使用されるアセンブリのx = globようなものとほぼ同じになります。しかし、この場合、どのプロセスがその行を呼び出しても、GOT のオフセット 0x10 にあるアドレスを持つ同じグローバル変数に常にアクセスすることは明らかです。では、2 つのプロセスが同じ GOT エントリを参照する同じテキスト セクションを使用する場合、どのようにしてグローバル変数の異なるコピーを持つことができるのでしょうか?mov eax,DWORD PTR [ecx-0x10]ecx

4

2 に答える 2

7

おそらく、ページ テーブルとコピー オン ライトのセマンティクスを理解していることでしょう。

a.outいくつかのグローバル データを初期化し、次にfork()sを初期化する実行可能ファイルを実行するとします。のすべての読み取り専用 (コードなど) ページがa.out2 つのプロセス間で共有されていることを理解するのに苦労することはほとんどありません (物理メモリのまったく同じmmapページが両方の仮想メモリ空​​間に ed されます)。

これもing の前にa.out使用されたとします。に属する読み取り専用ページもまったく同じ方法でプロセス間で共有されることを理解するのに問題はありません。libc.so.6forklibc.so.6

ここで、2 つの別個の実行可能ファイル と がa.outありb.out、両方とも を使用しているとしlibc.so.6ます。a.out が最初に実行されるとします。動的ローダーは、仮想メモリ空​​間への読み取り専用マッピングを実行し、そのページの一部が物理メモリに配置されlibc.so.6ます。a.outその時点でb.out、動的ローダーが開始されmmap、同じlibc.so.6ページが仮想メモリに読み込まれます。カーネルにはこれらのページのマッピングが既にあるため、カーネルがマッピングを保持するために新しい物理ページを作成する理由はありません。以前にマップされた物理ページを再利用できます。最終結果はforked バイナリの場合と同じです。同じ物理ページが複数の仮想メモリ空​​間 (および複数のプロセス) 間で共有されます。

では、2 つのプロセスがグローバル変数の異なるコピーを持つにはどうすればよいでしょうか。

非常に単純です: 読み取り/書き込みマッピング (書き込み可能なデータに必要) はプロセス間で共有されません(そのため、1 つのプロセスが変数に書き込むことができ、その書き込みは他のプロセスには見えません)。

于 2018-10-31T02:42:06.720 に答える