Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
У. Столлингс ГЛАВА 5 Многопроцессорные вычислен...doc
Скачиваний:
0
Добавлен:
01.03.2025
Размер:
2.98 Mб
Скачать

Приоритетное чтение

В листинге 5.19 приведено решение задачи с использованием семафоров для варианта, в котором имеются один читатель и один писатель (решение не требу­ет изменений, если имеется много читателей и писателей). Процесс писателя очень прост. Для обеспечения взаимного исключения используется семафор wsem. Когда один писатель записывает данные, ни другие писатели, ни читатели не могут получить к ним доступ. Процесс читателя также использует семафор wsem для обеспечения взаимоисключений. Однако чтобы обеспечить возможность одновременной работы многих читателей, состояние семафора проверяет только читатель, входящий в критический раздел, в котором нет других читателей. Ес­ли в критическом разделе уже находится хоть один читатель, то другой читатель приступает к работе, не ожидая семафора wsem. Для отслеживания количества Читателей в критическом разделе используется глобальная переменная readcount, а для гарантии корректного ее обновления — семафор х.

Листинг 5.19. Решение задачи читателей/писателей с использованием семафоров (приоритетное чтение)

int readcount;

semaphore x = 1, wsem =1;

void reader()

{

while(true)

{

wait(x);

readcount++;

if (readcount==l)

. wait(wsem);

signal(x);

READUNIT();

wait(x);

readcount--;

if (readcount==0)

signal(wsem);

signal(x);

}

}

void writer()

{

while(true)

{

wait(wsem);

WRITEUNIT() ;

signal(wsem);

}

}

void main() {

readcount = 0;

parbegin(reader, writer);}

Приоритетная запись

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

В листинге 5.20 показано решение, обеспечивающее выполнение следую­щего условия: ни один читатель не сможет обратиться к данным, если хотя бы один писатель объявил о своем намерении произвести запись. Для этого к имеющимся в программе семафорам и переменным процесса писателя добавле­ны следующие:

• семафор rsem, запрещающий вход читателей, если хотя бы один писатель объявил о намерении произвести запись;

  • переменная writecount, обеспечивающая корректность установки значения rsem;

• семафор у, гарантирующий корректность изменения переменной writecount.

Листинг 5.20. Решение задачи читателей/писателей с использованием семафоров (приоритетная запись)

int readcount, writecount;

semaphore x = 1, y=l, z=l,

rsem = 1, wsem = 1;

void reader()

{

while (true)

{

wait (z) ;

wait(rsem);

wait(x) ;

readcount++;

if (readcount==l)

wait(wsem);

signal(x);

signal(rsem);

signal(z);

READUNIT ();

wait(x);

readcount--;

if (readcount==0)

signal(wsem); signal(x);

}

}

void writer()

{

while(true)

{

wait(y);

writecount++;

if (writecount==l)

wait(rsem);

signal(y);

wait(wsem);

WRITEUNIT();

signal(wsem);

wait(y);

writecount--;

if (writecount==0)

signal(rsem);

signal(y);

}

}

Таблица 5.5. Состояния очередей процессов в программе из листинга 5.20

В системе имеются только читатели • Устанавливается wsem

• Очередей нет

В системе имеются только писатели • Устанавливаются wsem и rsem

• Очередь писателей на wsem

В системе имеются как читатели, • wsem устанавливается читателем

так и писатели; первым выполняется • rsem устанавливается писателем

чтение

• Все писатели становятся в очередь на wsem • Один читатель становится в очередь на rsem • Остальные читатели становятся в очередь на z

В системе имеются как читатели, • wsem устанавливается писателем

так и писатели; первой выполняется • rsem устанавливается писателем

запись

• Все писатели становятся в очередь на wsem • Один читатель становится в очередь на rsem • Остальные читатели становятся в очередь на z

В листинге 5.21 приведено еще одно решение задачи с приоритетной запи­сью, реализованное с использованием системы передачи сообщений. В этом слу­чае имеется управляющий процесс с правом доступа к совместно используемым данным. Прочие процессы запрашивают право доступа к данным, посылая сооб­щение управляющему процессу. Запрашивающий процесс получает право досту­па посредством ответного сообщения "ОК", а после завершения работы сообщает об этом специальным сообщением finished. У управляющего процесса имеются три почтовых ящика, по одному для каждого типа получаемых им сообщений.

Листинг 5.21. Решение задачи читателей/писателей с использованием системы передачи сообщений

void reader(int i)

{

message rmsg; while(true)

{

rmsg = i;

send(readrequest,rmsg);

receive(mbox[i] ,rmsg);

READUNIT();

rmsg = i;

send(finished,rmsg) ;

}

}

void writer(int j)

{

message rmsg;

while(true)

{

rmsg = i;

send(writerequest,rmsg);

receive(mbox[ j ] ,rmsg);

WRITEUNIT() ;

rmsg = i;

send(finished, rmsg) ;

}

}

void controller ()

{

while(true)

{

if (count > 0)

{

if (!empty(finished))

{

receive(finished,msg);

count++;

}

else if (!empty(writerequest))

{

receive(writerequest,msg);

writer_id = msg.id;

count = count - 100;

}

else if (!empty(readrequest))

{

receive(readrequest,msg);

count--;

send(msg.id,"OK");

}

}

if (count == 0)

{

send(writer_id,"OK");

receive(finished,msg);

count = 100;

}

while(count < 0)

{

receive(finished,msg);

count++;

}

}

}

Первыми управляющий процесс обслужит запросы на запись, давая таким образом приоритет операции записи; кроме того, управляющий процесс обеспе­чивает выполнение взаимоисключений, для чего используется переменная count, инициализируемая неким числом, которое заведомо больше максимально возможного количества читателей. В нашем примере использовано значение 100. Действия управляющего процесса можно описать следующим образом.

  • Если count>0, значит, ожидающих писателей нет; активные читатели мо­гут как присутствовать, так и отсутствовать. Управляющий процесс обслу­живает сначала все сообщения типа finished, а затем запросы от писате­лей и читателей.

  • Если count=0, это означает, что у нас имеется только запрос на запись. Управляющий процесс дает писателю "добро" на выполнение своих дейст­вий и ожидает от него сообщения о завершении работы.

  • Если count<0, значит, писатель сделал запрос и ожидает завершения рабо­ты всех активных читателей, так что управляющий процесс при этом при­нимает только сообщения о завершении работы читателей.