виртуальная адресация vs. физическая адресация

Я не совсем понимаю преимущества "нескольких независимых виртуальных адресов, указывающих на один и тот же физический адрес", хотя я прочитал много книг и статей,

Например, в аналогичном вопросе Разница между концепцией физической адресации и виртуальной адресации,

В посте утверждается, что программы не будут сбивать друг друга, и

«как правило, конкретная физическая страница отображается только в виртуальное пространство одного приложения»

Ну, в http://tldp.org/LDP/tlk/mm/memory.html в разделе "общая виртуальная память" написано

«Например, в системе может быть несколько процессов, выполняющих командную оболочку bash. Вместо того, чтобы иметь несколько копий bash, по одной в виртуальном адресном пространстве каждого процесса, лучше иметь только одну копию в физической памяти и все запущенные процессы. поделись».

Если один физический адрес (например, программа-оболочка) сопоставлен с двумя независимыми виртуальными адресами, как это может не дать сбой? Разве это не то же самое, что использовать физическую адресацию?

что дает виртуальная адресация, что невозможно или удобно при физической адресации? Если виртуальной памяти не существует, то есть две прямо указывают на одну и ту же физическую память? я думаю, используя какой-то механизм координации, это все еще может работать. Так зачем вообще заниматься «виртуальной адресацией, MMU, виртуальной памятью»?




Ответы (2)


Если один физический адрес (например, программа-оболочка) сопоставлен с двумя независимыми виртуальными адресами

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

Кроме того, «несколько процессов в системе, выполняющих командную оболочку bash» из примера, будут совместно использовать доступную только для чтения часть своих адресных пространств, которая включает в себя код. Они могут одновременно выполнять один и тот же код в памяти и не будут убивать друг друга, поскольку не могут его модифицировать.

В цитате

как правило, конкретная физическая страница сопоставляется только с виртуальным пространством одного приложения.

часть «в целом» должна быть «обычно»: страницы памяти не являются общими, если вы не настроили их так, или если они не доступны только для чтения.

person Fred Foo    schedule 15.07.2011
comment
Привет, larsmans, большое спасибо за комментарии. Но все же, что дает виртуальная адресация, что невозможно или удобно при физической адресации? что именно стоит, если виртуальной памяти не существует, т.е. две прямо указывают на одну и ту же физическую память? я думаю, используя какой-то механизм координации, это все еще может работать. Так зачем вообще виртуальная адресация, MMU, виртуальная память? - person pepero; 15.07.2011
comment
@pepero: виртуальная память — это абстракция над физической памятью, благодаря которой каждый процесс не замечает друг друга, обеспечивая защиту своего адресного пространства именно от переполнений, которых вы опасаетесь. Кроме того, без виртуальной адресации каждый процесс должен при запуске определять, где находится его код и данные, и соответствующим образом устанавливать свои указатели. Если он совершит ошибку, он может повредить свою собственную память или память других процессов. - person Fred Foo; 15.07.2011

Есть два основных варианта использования этой функции.

Во-первых, вы можете разделить память между процессами, которые могут общаться через общие страницы. На самом деле разделяемая память — это одна из самых простых форм IPC.

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

Этот трюк улучшен с помощью «копирования при записи». Код исполняемых файлов обычно не меняется при запуске, но есть программы, которые на самом деле являются самомодифицирующимися (они были довольно распространены в прошлом, когда большая часть разработки все еще выполнялась на ассемблере); чтобы поддерживать этот материал, операционная система делает общий доступ только для чтения, как объяснялось ранее, но, если она обнаруживает запись на одной из общих страниц, она отключает общий доступ для такой страницы, создавая ее независимую копию и позволяя программе писать там.

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

Другой случай, в котором можно использовать этот метод, — это когда процесс разветвляется: вместо копирования каждой страницы памяти (что совершенно бесполезно, если дочерний процесс немедленно выполняет exec), новый процесс делится с родительским процессом всеми своими страницами памяти в копии на режим записи, позволяющий быстро создавать процессы, по-прежнему «имитируя» «классическое» поведение форка.

person Matteo Italia    schedule 15.07.2011