Linuxに 2 つのプロセスがあるa
とb
します。両方のプロセスでmalloc()
、メモリを割り当てるために使用します。
malloc()
2 つのプロセスで同じ開始アドレスを返す可能性はありますか? いいえの場合、誰がこれを処理しますか。はいの場合、両方のプロセスがこのアドレスで同じデータにアクセスできます。
Linuxに 2 つのプロセスがあるa
とb
します。両方のプロセスでmalloc()
、メモリを割り当てるために使用します。
malloc()
2 つのプロセスで同じ開始アドレスを返す可能性はありますか? いいえの場合、誰がこれを処理しますか。はいの場合、両方のプロセスがこのアドレスで同じデータにアクセスできます。
2 つのプロセスで malloc() が同じ開始アドレスを返す可能性はありますか。
はい、問題ありません。
あなたが理解していないのは、オペレーティングシステムが最初に物理空間を処理するということです-プログラムなどは仮想アドレスしか認識しません。仮想アドレス空間は 1 つしかありませんが、オペレーティング システム (ここでは 32 ビットに固執しましょう) がそれを分割します。Windows では、上半分 (0xA0000000+) はカーネルに属し、下半分はユーザー モード プロセスに属します。これは、2GB/2GB 分割と呼ばれます。Linux では、分割は 3GB/1GB です。次の記事を参照してください。
カーネル メモリは、PAGE_OFFSET (x86 では 0XC0000000、つまり 3 ギガバイト) から始まるように定義されています。(ここで 3gig/1gig 分割が定義されます。) PAGE_OFFSET より上にあるすべての仮想アドレスはカーネルであり、PAGE_OFFSET より下にあるすべてのアドレスはユーザー アドレスです。
これで、(コンテキスト スイッチではなく) プロセス スイッチが発生すると、現在のプロセスに属するすべてのページが仮想メモリからマップ解除され (ページングする必要はありません)、実行されるプロセスに属するすべてのページがマップされます。にコピーされます (免責事項: これは正確には正しくない可能性があります。理論的には、ページにダーティなどのマークを付けて、代わりにアクセス時にコピーすることができます)。
分割の理由は、パフォーマンス上の理由から、仮想メモリ空間の上半分がオペレーティング システム カーネルにマップされたままになる可能性があるためです。
そのため、malloc は 2 つの特定のプロセスで同じ値を返す可能性がありますが、それは問題ではありません。
64 ビット システムの場合、現在これらのビットのうち 48 ビットしか使用していないため、ユーザー モードの下部とカーネル モードの間にギャップがあり、(まだ) アドレス指定できません。
はい、malloc()
プロセスが別々のアドレス空間で実行されている場合、別々のプロセスで同じポインタ値を返すことができます。これは、仮想メモリを介して実現されます。ただし、その場合、同じ物理メモリの場所にアクセスすることはなく、アドレスのデータが同じである必要はありません。
プロセスは、スレッドとアドレス空間のコレクションです。このアドレス空間は、そのすべてのバイトが必ずしも物理メモリに支えられているとは限らないため、仮想と呼ばれます。仮想アドレス空間のセグメントは、プロセス内のアプリケーションがこのメモリを効果的に使用して終了した場合、最終的に物理メモリによってバックアップされます。
そのmalloc()
ため、2 つのプロセスに対して同一のアドレスが返される場合がありますが、これらの割り当てられたメモリは物理メモリの異なるセグメントによってサポートされるため、問題はありません。
さらにmalloc()
、実装はほとんど再入可能ではないためmalloc()
、同じアドレス空間を共有する別のスレッドを呼び出しても、同じ仮想アドレスが返されることはありません。