2012-07-04 3 views
4

Предположим, у меня есть два процесса a и b на Linux. и в обоих процессах я использую malloc() для выделения памяти,Может malloc вернуть тот же адрес в двух разных процессах?

Есть ли шансы, что malloc() возвращает тот же начальный адрес в два процесса? Если нет, то кто позаботится об этом. Если да, то оба процесса могут получить доступ к тем же данным по этому адресу.

+0

Мы используем виртуальные адреса! – phoxis

ответ

11

Есть ли какие-либо шансы, что malloc() возвратит тот же начальный адрес в два процесса.

Да, но это не проблема.

Что вы не понимаете, так это то, что операционные системы сначала обрабатывают ваше физическое пространство - программы и т. Д. Видят только виртуальные адреса. Существует только одно виртуальное адресное пространство, однако операционная система (давайте придерживаться 32-битной версии) делит это. В Windows верхняя половина (0xA0000000 +) относится к процессам ядра и нижней половины к пользовательскому. Это называется разделение 2 ГБ/2 ГБ. В Linux, разрыв составляет 3GB/1GB - см this article:

памяти ядра определяется начать в PAGE_OFFSET, что в x86 является 0xC0000000, или 3 гигабайта. (Здесь определяется разделение 3gig/1gig.) Каждый виртуальный адрес выше PAGE_OFFSET является ядром, любой адрес ниже PAGE_OFFSET является адресом пользователя.

Теперь, когда происходит переключение процессов (в отличие от переключения контекста), все страниц, принадлежащих к текущему процессу являются некартированными из виртуальной памяти (не обязательно пейджинговые их) и все страниц, принадлежащие к (отказ от ответственности: это может быть не совсем верно, можно было бы пометить страницы грязными и т. д. и скопировать на доступ, теоретически).

Причина разделения заключается в том, что по соображениям производительности верхняя половина пространства виртуальной памяти может отображаться в ядре операционной системы.

Таким образом, хотя таНос может возвращать то же значение в двух заданных процессов, что не имеет значения, потому что:

  1. физически, они не тот же адрес.
  2. Процессы не обмениваются виртуальной памятью в любом месте.

Для 64-разрядных систем, поскольку в настоящее время мы используем только 48 из этих битов, существует залив между нижней частью пользовательского режима и режимом ядра, который не адресуется (пока).

+0

На самом деле это 3GB/1GB split, 0xc0000000 - это начальный адрес последнего гигабайта 32-разрядного адресного пространства. – Benoit

+0

@Benoit, в этом случае, я заполнил свои номера. Обычно это разделение на 2 ГБ/2 ГБ на Windows, если вы явно не попросите его ['/LARGEADDRESSAWARE'](http://msdn.microsoft.com/en-us/library/wz223b1z(v=vs.80).aspx) –

+1

Я не знал, для Windows, для информации. Я отметил, что, поскольку пространство ядра Linux начинается с 0xc0000000, как вы его упомянули. – Benoit

2

Да, malloc() может возвращать одно и то же значение указателя в отдельных процессах, если процессы выполняются в отдельных адресных пространствах, что достигается посредством виртуальной памяти. Но в этом случае они не будут иметь доступ к одному и тому же физическому местоположению, а данные по адресу, очевидно, не обязательно совпадают.

1

Процесс представляет собой набор потоков плюс адресное пространство. Это адресное пространство называется virtual, потому что каждый его байт не обязательно поддерживается физической памятью. Сегменты виртуального адресного пространства в конечном итоге будут поддерживаться физической памятью, если приложение в этом процессе завершится эффективным использованием этой памяти.

Так, malloc() может возвращать одинаковый адрес для двух процесса, но это не является проблемой, так как эти malloced воспоминания будут поддержаны различными сегментами физической памяти.

Кроме того, malloc() реализация является moslty not reentrant, поэтому вызов malloc() в разных потоках, разделяющих одно и то же адресное пространство, надеюсь, не приведет к возврату того же виртуального адреса.

+0

«надеюсь»? Вы имеете в виду «в основном реентерабельный/поточно-безопасный»? –

+0

Два потока, вызывающие 'malloc()', не могут одновременно изменять структуру бухгалтерии. Некоторые mecanisms должны делать 'malloc()' тип потокобезопасного, да. – Benoit

+0

Истина, либо внутри malloc()/free(), либо снаружи. –

Смежные вопросы