Chapter_11 (1110563), страница 2
Текст из файла (страница 2)
На современных ЭВМ,однако, появился механизм виртуальной памяти, который обеспечивает большое логическое адресное пространство (сейчас – порядка 232 байт, а в дальнейшем будет ещё больше). Это позволилоработать с очень большим (виртуальным) рабочим полем и назначать каждой процедуре свой диапазон адресов, несовпадающий с диапазонами адресов других процедур, таким образом, перемещаемость перестала быть важной характеристикой исполняемых модулей.211.2.2. Повторно-выполняемые модулиПовторное выполнение модуля предполагает, что, будучи один раз загруженным в оперативнуюпамять, он допускает своё многократное исполнение (т.е.
вход в начало этого модуля после его завершения). Естественно, что процедуры и функции по определению являются повторно используемыми, однако для основной (головной) программы дело обстоит сложнее. Какими свойствами должна обладать программа, чтобы после, например, окончания счёта по макрокоманде finish быловозможно снова войти в начало программы по метке Start, не загружая эту программу заново воперативную память?Естественно, что, прежде всего, необходимо восстановить для программы первоначальный (пустой) стек, однако этого может оказаться недостаточно.
Легко понять, что для головной программы наАссемблере должно выполняться следующее условие: программа не должна менять свои кодовыесегменты и переменные с начальными значениями в сегментах данных, или, в крайнем случае, вос1Для продвинутых читателей заметим, что такой модуль можно перемещать с одного места памяти в другое не в любой момент, а только тогда, когда он не считается (например, если он вызвал внешнюю процедуру).В частности заметим, что нельзя перемещать модуль в другое место памяти во время выполнения им системного вызова по команде int i8 , так как возврат из процедуры-обработчика прерывания производится по команде iret , которая, как мы знаем, в частности восстанавливает и значение регистра счётчика адреса IP.2Подробную организацию виртуальной памяти студенты факультета вычислительной математики и кибернетики МГУ изучают в курсе третьего семестра "Системное программное обеспечение".4станавливать эти значения перед окончанием программы.
Например, если в программе на Ассемблере имеются предложенияXdw1. . .mov X,2то программа будет повторно используемой только тогда, когда она восстанавливает первоначальноезначение переменной X перед выходом из программы. В настоящее время это свойство программы неимеет большого значения, потому что появилось более сильное свойство модуля – быть повторновходимым (реентерабельным).11.2.3. Повторно-входимые (реентерабельные) модулиСвойство исполняемого модуля быть реентерабельным (иногда говорят – параллельно используемым) является очень важным, особенно при написании системных программ. Модуль называетсяреентерабельным, если он допускает повторный вход в своё начало до выхода из этого модуля (длямодулей на Ассемблере, как мы знаем, выход производится по команде возврата ret для процедур,по команде iret для обработчиков прерываний или по макрокоманде finish для основной программы).Особо подчеркнём, что повторный вход в такой модуль производит не сам этот модуль, используя прямую или косвенную рекурсию (в этом случае говорят о вызове модуля), а другие программы,обычно при обработке сигналов прерываний.
Таким образом, внутри реентерабельного модуля могутрасполагаться несколько текущих точек выполнения этой программы. Мы уже сталкивались с такойситуацией при изучении системы прерываний, когда выполнение процедуры-обработчика прерывания с некоторым номером могло быть прервано новым сигналом прерывания с таким же номером,так что производился повторный вход в начало этой же процедуры до окончания обработки текущего прерывания.Каждая текущая точка выполнения реентерабельной программы имеет, как мы уже упоминали,своё поле сохранения (иногда его называют контекстом процесса). При прерывании выполненияпрограммы на этом поле сохраняются, в частности, все регистры, определяющие текущую точку выполнения.
Это как сегментные регистры и регистр флагов, так и регистры общего назначения, а такжерегистры для работы с вещественными числами, и специальные системные (невидимые программисту) регистры.Главное отличие реентерабельных программ от обычных рекурсивных процедур заключаетсяименно в том, что, в отличие от вызова программы, при каждом входе в реентерабельную программу порождается новая текущая точка её выполнения и порождается новое поле сохранения. Это позволяет продолжить выполнение реентерабельной программы с любой из этих нескольких текущихточек выполнения программы, восстановив значения всех её регистров из поля сохранения этой точки программы.1На рис.
11.2 показан пример реентерабельной программы с тремя точками выполнения, отмеченными значениями регистра счётчика адреса IP. Какая-нибудь из этих точек в данный момент можетбыть активной, т.е. в ней находится центральный процессор, выполняя команды программы. Возможен, однако, и случай, когда все эти три вычислительных процесса находятся в состоянии ожидания, а центральный процессор занят выполнением какой-либо другой программы.Принцип выполнения реентерабельных программ можно пояснить на таком шутливо-детективном примере. Вернувшись из очередного отпуска, следователь по особо важным делам майор Пронинпринял к производству дело опасного преступника X.
Произведя первые допросы свидетелей, и приобщив их к материалам дела, Пронин был вынужден прервать данное расследование, так как его попросили срочно заняться новым преступлением, которое предположительно совершил вор-рециди-1Вообще говоря, здесь ситуация сложнее, чем мы её описываем. Для возобновления счёта программы спрерванного места необходимо, кроме регистров, восстановить из контекста процесса ещё значения специальных служебных переменных (их часто называют переменными окружения программы). В этих переменных,например, хранится информация обо всех файлах, с которыми работает программа. Ясно, что в разных точкахмодуля может производиться и обработка разных файлов. Таким образом, под контекст процесса необходимоотводить достаточно большую область памяти (порядка килобайта).5вист Y.1 Найдя в новом деле первые улики и отправив их на экспертизу, которая должна была занятьнесколько дней, Пронин вернулся к делу преступника X, но вскоре после этого ему позвонил его начальник полковник Петренко и приказал немедленно заняться делом серийного убийцы Z… Стоитпожалеть майора Пронина и разрешить ему хотя бы в воскресенье поехать на дачу и совсем не заниматься расследованиями ☺.РеентерабельнаяпрограммаIP1Область сохранения №1IP2Область сохранения №2IP3Область сохранения №3Рис.
11.2. Реентерабельная программа с тремя точками выполнения.Как видим, следователь Пронин может возобновить расследование любого порученного ему дела, освежив свою память материалами из соответствующей папки (или из компьютерного файла, еслимайор Пронин шагает в ногу со временем). Точно так же и выполнение реентерабельной программыможно продолжить с любого прерванного места, так как вся необходимая для продолжения работыинформация находится в соответствующей области сохранения.
Как видим, в нашей аналогии майорПронин играет роль центрального процессора, а дела, которые он ведёт – это процессы одной общейреентерабельной "программы расследования преступлений".Таким образом, одна реентерабельная программа, находясь в памяти ЭВМ, может породить неодин, а несколько самостоятельных (независимых друг от друга) вычислительных процессов(обычно слово "вычислительных" опускают, и называют их просто процессами).
В нашем примерена рис. 11.2 для служебной программы, управляющей счётом задач (эта программа операционнойсистемы чаще всего называется диспетчером процессов), для одной копии реентерабельной программы в памяти будут существовать три независимых единицы работы – три процесса.2Как можно заметить, каждый процесс может находиться в одном из следующих состояний:•Процесс выполняется на центральном процессоре (майор Пронин допрашивает серийногоубийцу Z).•Процесс готов к счёту, но центральный процессор занят другим процессом (преступник Xждёт в КПЗ, пока майор Пронин не вызовет его на допрос).•Процесс не готов к счёту и чего-то ждёт (майор Пронин ждёт результата экспертизы поделу вора-рецидивиста Y).•Процесс завершён, но ещё не удалён из списка процессов диспетчера (производство по делузавершено, но само дело ещё не сдано в архив, так как ожидается, например, решение суда).3Ниже перечислены основные свойства, которыми должен обладать модуль на Ассемблере, чтобыбыть реентерабельным.1Мы предполагаем, что, подобно большинству людей, майор Пронин не может вести два дела по настоящему одновременно, подобно тому, как компьютер, обладающий только одним центральным процессором, в каждый момент времени может считать только одну программу.
Людей, которые могут на самом деле одновременно заниматься несколькими разными делами, очень мало. По преданию, одним из них был знаменитыйдревнеримский император Юлий Цезарь, который мог слушать доклад одного чиновника, отдавать приказаниядругому и одновременно писать письмо по совершенно иной теме. Заметим, что среди компьютеров массовогопроизводства до недавнего времени (до широкого распространения многоядерных процессоров) тоже было мало многопроцессорных ЭВМ.2Информация к размышлению: должен ли сам диспетчер также выполняется в виде процесса и, следовательно, управлять самим собой?3В операционной системе Unix такие процессы носят экзотическое название "зомби", они "не совсеммертвы" и не удаляются до тех пор, пока некоторые из выполняющихся процессов могут "поинтересоваться" ихсудьбой (например, закончились ли они нормально или аварийно, сколько использовали ресурсов и т.д.).6••Модуль не изменяет свои сегменты кода.Модуль либо совсем не имеет собственных сегментов данных (т.е.
все данные передаютсяему в качестве параметров), либо при каждом входе получает новые копии своих сегментовданных.•При каждом входе в модуль он получает новый сегмент стека, пустой для основной программы и с копиями фактических параметров и адресом возврата для процедуры. Вообщеговоря, этот сегмент стека является возможным местом и для расположения области сохранения модуля, хотя на современных ЭВМ область сохранения обычно размещается втак называемом пространстве ядра операционной системы, это место является надёжно защищённым от изменения со стороны программ обычных пользователей.Таким образом, получается, что порождаемые из реентерабельной программы процессы имеютобщие сегменты кода, но раздельные сегменты данных и стека.1Реентерабельность является особенно важной при написании программ, входящих в состав операционных систем и систем программирования.