Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Разделение общих процедур






В мультипрограммной системе желательно, чтобы несколько пользователей могли разделять процедуры. Такими процедурами, называемыми общими, обычно являются библиотечные или системные программы, например драйверы ввода-вывода, процедуры преобразований кодов и т. п. Например, несколько пользователей могут одновременно пожелать редактировать свои программы с помощью редактора текста. Если не разделять код, в память придется загрузить несколько копий редактора. При разделении кода потребуется иметь в памяти только одну копию, что дает значительную экономию объема памяти.

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

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

1. Процесс 1 выполняется и вызывает реентерабельную процедуру.

2. Реентерабельная процедура помещает промежуточный результат в ТНМР.

3. Процесс 2 получает управление процессором.

4. Процесс 2 вызывает реентерабельную процедуру.

5. Реентерабельная процедура вновь помещает промежуточный результат в TEMP.

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

Чтобы решить данную задачу, все результаты, включая и содержимое регистров, должны храниться в ячейках, ассоциированных с вызывающим процессом. В приведенном примере два промежуточных результата необходимо поместить в отдельные ячейки, одна из которых ассоциирована с процессом 1, а другая — с процессом 2. Для хранения многих копий промежуточных результатов по принципу LIF0 применялся один и тот же стек, так как рекурсивные вызовы сопровождаются возвратами в обратном порядке. Здесь же информация запоминается в вызывающем процессе.

 

 

Рис. 7.7. Реентерабельная процедура, разделяемая двумя процессами

 

В процессорах, имеющих стек, обычный способ хранения промежуточных результатов заключается в том, чтобы ассоциировать стек с каждым процессом. На рис. 7.7 показано, как два процесса обращаются к реентерабельной процедуре. Когда процесс 1 вызывает реентерабельную процедуру, содержимое регистров SS и SP не изменяется и реентерабельная процедура запоминает любые свои результаты в стеке процесса 1. Когда происходит переключение процессов, содержимое SS и Spизменяется с тем, чтобы адресовать вершину стека, ассоциированного с процессом 2. Когда вновь вызывается реентерабельная процедура, она будет запоминать свои результаты в стеке, ассоциированном с процессом 2, а предыдущие результаты не искажаются.

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

Чистый код в реентерабельной процедуре должен быть еще и позиционно-независимым, т. е, он может правильно выполняться независимо от его размещения в физической памяти или относительно вызывающих его процессов. Во всех локальных обращениях должна применяться какая-либо разновидность косвенной адресации или код должен корректировать свои локальные адреса в соответствии с текущим размещением. Лучшим методом образования позиционно-независимого кода оказывается относительная адресация, которая в ЦП реализуется с помощью сегментных регистров. Требование позиционной независимости реентерабельных процедур объясняется тем, что они разделяются несколькими процессами и обычно во время выполнения динамически связываются с различными процедурами. Такая связь упрощается, если адреса в реентерабельном коде модифицировать не нужно.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.