Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
VSOS_2014.doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
1.9 Mб
Скачать

24Задача об обедающих философах

Представим пять философов, проводящих свою жизнь в раздумьях и еде. Они разделяют общий круглый стол с пятью стульями вокруг, каждый из которых принадлежит одному философу. В центре стола находится блюдо с рисом, между тарелками лежат одиночные палочки для риса. Когда философ думает, он не общается с коллегами. Время от времени, проголодавшись, философ пытается схватить две палочки, лежащие слева и справа от его тарелки. Философ может взять за один прием только одну палочку. Естественно, он не может взять палочку, если она в руках у соседа. Приступить к еде философ может только, если у него в руках две палочки. Когда философ заканчивает еду, то он кладет обе палочки на место и снова начинает думать.

Задача об обедающих философах рассматривается как классическая задача синхронизации не из-за ее практической ценности, не потому, что ученые-компьютерщики не любят философов, а из-за того, что она представляет большой класс задач параллельного доступа. Она является простым примером необходимости предоставления нескольких ресурсов нескольким процессам.

Простейшее решение – представить каждую палочку в виде семафора. Философ пытается захватить палочку выполнением операции wait, а освобождает ее с помощью операции signal.

var chopstick: array[0..4] of semaphore;

Каждый элемент массива первоначально инициализируется значением 1.

Схема работы i-го философа будет следующей:

repeat

wait(chopstick[i]);

wait(chopstick[(i+1) mod 5]);

. . .

eat

. . .

signal(chopstick[i]);

signal(chopstick[(i+1) mod 5]);

. . .

think

. . .

until false;

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

Перечислим возможные решения проблемы:

  • разрешить не более, чем четырем философам одновременно садиться за стол;

  • разрешить философу брать палочки, только если обе палочки свободны (появится критический участок);

  • использовать асимметричное решение: нечетный философ сначала берет левую палочку, а четный – правую.

Кроме того, любое решение задачи должно учитывать возможность, что один из философов может умереть от голода. Решение, не допускающее тупика, не обязательно исключает подобную развязку.

    1. Двоичные семафоры

Двоичный семафор – это переменная, которая может принимать только два значения: 0 и 1. Такой семафор проще для реализации с точки зрения компьютерной системы. Однако такие семафоры сложнее для использования.

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

var s1,s2,s3: binary_semaphore;

c: integer;

Начальное значение семафоров s1 и s3 – 1, семафора s2 – 0, начальное значение переменной c равно начальному значению счетчика.

Тогда операцию wait можно выразить следующим образом:

wait(s3);

wait(s1);

с := c - 1;

if c<0 then

begin

signal(s1);

wait(s2);

end

else

signal(s1);

signal(s3);

Операция signal будет описываться так:

wait(s1);

с := c + 1;

if c<=0 then

signal(s2);

signal(s1);

Заметим, что двоичный семафор s2 влияет только на работу операции wait.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]