Читайте также: |
|
На рис. 5.3 показана первая версия программного кода для реализации взаимоисключения в контексте параллельной программы с двумя процессами. Конструкция parbegin/parend позволяет организовать параллельную работу процессов «процессодин» и «процессдва». Каждый из этих процессов представляет собой бесконечный цикл с многократным вхождением в свой критический участок. В программе рис. 5.3 примитив «входвзаимоисключения» реализуется как один цикл while, который повторяется до тех пор, пока переменная «номер процесса» не станет равной номеру данного процесса, примитив «выходвзаимоисключения» реализуется как одна команда, которая устанавливает для переменной «номерпроцесса» значение, равное номеру другого процесса.
«Процессодин» выполняет свой цикл. Поскольку первоначально переменная «номер процесса» имеет значение 1, «процессодин» входит в свой критический участок. «Процессдва» обнаруживает, что «номерпроцесса» равен 1 и остается заблокированным на своем цикле while do. Если «процессдва» получает в свое распоряжение процессор, он просто выполняет цикл ожидания момента, когда для переменной «номерпроцесса» будет установлено значение 2, т. е. «процессдва» не может войти в свой критический участок и тем самым гарантируется взаимоисключение.
В конце концов «процессодин» закончит работу в своем критическом участке (мы должны предполагать, что здесь нет бесконечных циклов) и установит «номерпроцесса» равным 2, так что «процессдва» получит возможность входа в свой критический участок.
program версияодин;
var номерпроцесса: целое;
procedure процессодин;
Begin
while истина begin
while номерпроцесса = 2 do;
критическийучастокодин;
номерпроцесса: = 2;
прочиеоператорыодин
End
End;
procedure процессдва;
Begin
while истина do begin
while номерпроцесса = 1 do;
критическийучастокдва;
номерпроцесса: = 1;
прочиеоператорыдва
End
End;
Begin
номерпроцесса:= 1;
Parbegin
процессодин;
процессдва parend
End;
Рис. 5.3 Программная реализация примитивов взаимоисключения (версия 1)
Программа рис. 5.3 гарантирует взаимоисключение, однако весьма дорогой ценой.
«Процессодин» должен выполняться первым, так что если «процессдва» готов к входу в свой критический участок, он может получить разрешение на это со значительной задержкой.
После того как «процессодин» войдет в свой критический участок и затем выйдет из него, должен будет выполняться «процессдва», даже если «процессодин» хочет вновь войти в свой критический участок, а «процессдва» еще не готов.
Таким образом, процессы должны входить и выходить из своих критических участков строго поочередно.
Если одному процессу приходится это делать во много раз чаще, чем другому, то он вынужден работать с гораздо меньшей скоростью, чем это необходимо.
Подобная программа не может оказаться в состоянии полного тупика; если оба процесса одновременно пытаются войти в свои критические участки, то, по крайней мере, одному из них удастся продолжить работу.
А если один из процессов завершится, то со временем другой окажется не в состоянии продолжать выполнение.
program версиядва;
var п1внутри, п2внутри: логический;
procedure процессодин;
Begin
while истина do
Begin
while п2внутри do;
п1внутри: = истина;
критическийучастокодин;
п1внутри: = ложь;
прочиеоператорыодин
End
End;
procedure процессдва;
Begin
while истина do
Begin
while п1внутри do;
п2внутри: = истина;
критическийучастокдва;
п2внутри: = ложь;
прочиеоператорыдва
End
End;
Begin
п1внутри: = ложь;
п2внутри: = ложь;
Дата добавления: 2015-02-16; просмотров: 110 | Поможем написать вашу работу | Нарушение авторских прав |