Из описания алгоритма следует, что все философы подчиняются одинаковым правилам.
Экономия.
Между переходами из состояния в состояние каждый философ отправляет и получает ограниченное число сообщений. А именно, если число соседей у философа равно d, то тогда этот философ отправит не более d и получит не более d сообщений, содержащих маркеры запроса или вилки. Действительно, предположим, что когда философ переходит в голодное состояние, у него содержится e "грязных" вилок. Тогда для получения недостающих вилок он должен отправить (d – e) запросов своим соседям. Кроме того, в худшем случае, до перехода в состояние приема пищи он может потерять все свои "грязные" вилки, и ему потребуется запросить их вновь. Т.к. философ находится в голодном состоянии при пересылке своей "грязной" вилки в этом же сообщении он может переслать и соответствующий ей маркер запроса. Поэтому для перехода из голодного состояния в состояние приема пищи потребуется не более чем 2d сообщений. В состоянии приема пищи и в состоянии размышления каждый философ может лишь получать сообщения с маркером запроса и отправлять вилки своим соседям, поэтому число получаемых и отправляемых сообщений также не превосходит 2d. В лучшем случае, когда все соседи философа постоянно находятся в состоянии размышления, он не будет получать от них запросов на вилки и может чередовать прием пищи и размышления вовсе без взаимодействия с ними.
Параллелизм.
Из правила перехода в состояние приема пищи следует, что представленный алгоритм координации действий философов не исключает возможности одновременного приема пищи для нескольких философов при условии, что они не являются соседями.
Ограниченность.
Число сообщений, находящихся в каждый момент времени в состоянии пересылки между любыми двумя философами, не превосходит двух: сообщение с маркером запроса и сообщение, содержащее передаваемую вилку.
В заключение еще раз отметим, что для традиционной задачи взаимного исключения граф конфликтов представляет собой полный граф, т.к. по постановке этой задачи при попытке доступа к КС процесс потенциально входит в конфликт с любым другим процессом, который может претендовать на доступ к этой же КС. В наихудшем случае для входа в КС процессу придется собрать (N – 1) вилок: по одной от каждого другого процесса в распределенной системе. Поэтому при использовании алгоритма обедающих философов для входа в КС потребуется обмен максимум 2(N – 1) сообщениями. Если же, начиная с некоторого момента, процесс перестанет запрашивать вход в КС, он рано или поздно отдаст все свои вилки другим процессам и не будет участвовать в обмене сообщениями. Таким образом, число сообщений, требуемых для работы с КС, в среднем будет пропорционально только числу процессов, активно работающих с этой КС.
Пример работы алгоритма обедающих философов для традиционной задачи взаимного исключения приведен на рис. 4.8. Каждый процесс (философ) Pi поддерживает работу с массивами forki[1..N], dirtyi[1..N] и reqfi[1..N] такими, что forki[j] = 1, когда Pi владеет общей с Pj вилкой, dirtyi[j] = 1, когда эта вилка "грязная", и reqfi[j] = 1, когда у Pi находится маркер запроса, соответствующий общей с Pj вилке. В противном случае элементы перечисленных массивов содержат ноль. Направление ребер в графе предшествования Н обозначено стрелками. На рис. 4.8а изображено начальное состояние системы: вилки распределены так, что граф Н не содержит циклов, и все процессы находятся в состоянии выполнения вне КС (в размышлениях), т.е. все вилки "грязные", и ни у одного из процессов одновременно с вилкой не находится соответствующий ей маркер запроса. На рис. 4.8б процессы Р2 и Р3 переходят в состояние запроса на вход в КС (голодное состояние) и запрашивают недостающие вилки у своих соседей. Когда процесс Pi запрашивает вилку у процесса Pj, элемент массива reqfi[j] сбрасывается в ноль. При получении процессом Pj запроса от Pi элемент массива reqfj[i] устанавливается в единицу. По правилу передачи вилки процесс P1 вынужден расстаться со своими вилками и передать их процессам P2 и P3, т.к. у Р1 находятся "грязные" вилки вместе с поступившими на них запросами, и, кроме того, Р1 не выполняется в КС (не принимает пищу). При передаче вилок они "очищаются" – см. рис. 4.8в.
(и)
Рис. 4.8. Пример работы алгоритма обедающих философов.
Обратим внимание, что на рис. 4.8в процесс Р2 содержит все необходимые ему вилки. При этом общая с Р1 вилка – "чистая", а общая с Р3 вилка – "грязная". Однако процесс Р2 не может войти в КС (начать прием пищи), т.к. вместе с "грязной" вилкой у него содержится запрос на нее от процесса Р3. Поэтому Р2 отправляет эту вилку процессу Р3, не забывая перед этим ее "почистить", как показано на рис. 4.8г. В итоге процесс Р3 получит "чистые" вилки от Р1 и Р2 и сможет войти в КС. С началом работы в КС все вилки процесса Р3 становятся "грязными": его приоритет по отношению к Р1 и Р2 понижается. Т.к. процесс Р2 находится в состоянии запроса на вход в КС, он отправляет запрос на только что отданную вилку процессу Р3. В свою очередь процесс Р3 не возвращает "грязную" вилку процессу Р2, т.к. в момент получения запроса процесс Р3 выполняется внутри КС. Эта ситуация проиллюстрирована на рис. 4.8д. На рис. 4.8е процесс Р1 переходит в состояние запроса на вход в КС и запрашивает вилки у своих соседей. Отметим, что процесс Р3 не отдает процессу Р1 "грязную" вилку,
т.к. выполняется в КС, а процесс Р2 не отдает процессу Р1 вилку, т.к. она – "чистая". Поэтому процессу Р1 придется ожидать до тех пор, пока Р3 не завершит свое выполнение в КС, и пока Р2 не войдет и не выйдет из КС. После завершения выполнения в КС процесс Р3 "очищает" все свои вилки и отдает их запрашивающим соседям – см. рис. 4.8ж. Обладая чистыми вилками, процесс Р2 сможет войти в КС, как показано на рис. 4.8з. С началом работы в КС Р2 понизит свой приоритет по отношению к Р1 и Р3. После завершения выполнения внутри КС, имея маркер запроса от Р1, процесс Р2 отдаст Р1 общую с ним вилку, после чего Р1 также получит возможность войти в КС, как показано на рис. 4.8и.
Do'stlaringiz bilan baham: |