Главная страница Случайная страница Разделы сайта АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Неполное решение задачи о парикмахерской
Основное тело программы активизирует процессы 50 клиентов, трех парикмахеров и одного кассира. Рассмотрим теперь назначение различных синхронизирующих операторов. · Вместимость парикмахерской и дивана. Вместимость парикмахерской и дивана управляется семафорами max_capacity и sofa, соответственно. Каждый раз при попытке клиента войти в парикмахерскую значение семафора max_capacity уменьшается на 1; когда клиент покидает парикмахерскую, оно увеличивается. Если парикмахерская заполнена, то процесс клиента приостанавливается функцией wait (max_capacity). Аналогично обрабатывается и попытка присесть на диван. · Емкость парикмахерских кресел. В наличии имеются три парикмахерских кресла, и следует обеспечить их корректное использование. Семафор barber_chair гарантирует одновременное обслуживание не более трех клиентов, так чтобы один клиент не оказался на коленях у другого. Клиент не поднимется с дивана до тех пор, пока не окажется свободным хотя бы одно кресло (вызов wait (barber_chair)), а каждый парикмахер сообщает о том, что его кресло освободилось (вызов signal (barber_chair)). Справедливый доступ к парикмахерским креслам гарантируется организацией очередей семафоров: клиент, который первым блокирован в очереди, первым же и приглашается на стрижку. Заметим, что если в процедуре клиента вызов wait (barber_chair) разместить после signal (sofa), то каждый клиент будет только присаживаться на диван, после чего немедленно вскакивать и занимать стартовую позицию у кресла, создавая излишнюю толкотню и мешая работать парикмахеру. · Размещение клиента в кресле. Семафор custready обеспечивает подъем спящего парикмахера, сообщая ему о новом клиенте. Без этого семафора парикмахер никогда не отдыхал бы и приступал к стрижке немедленно после того, как очередной клиент покинет кресло. При отсутствии клиента в этот момент парикмахер стриг бы воздух. · Удержание клиента в кресле. Если уж клиент оказался в кресле, он должен отсидеть там до окончания стрижки, о чем просигнализирует семафор finished. · Ограничение количества клиентов в креслах. Семафор barber_chair предназначен для ограничения количества клиентов в креслах — их не должно быть более трех. Однако одного семафора barber_chair для этого недостаточно. Клиент, который не получит процессорное время непосредственно после того, как парикмахер сообщит о завершении работы над его прической (вызов signal (finished)), останется в кресле (например, впав в транс или глубоко задумавшись о задаче о парикмахерской), в то время как в этом же кресле будет стараться устроиться новый клиент. Для решения данной задачи используется семафор leave_b_chair, который не позволяет парикмахеру пригласить нового клиента до тех пор, пока предыдущий не покинет кресло. · Оплата стрижки. Естественно, с деньгами надо быть особенно осторожным. Кассир должен быть уверен, что каждый клиент, покидая парикмахерскую, сперва расплатится, а каждый клиент, оплатив стрижку, должен получить чек. Это достигается передачей денег кассиру из рук в руки — каждый клиент, покинув кресло, оплачивает услуги парикмахера, после чего дает знать об этом кассиру (вызов signal (payment)) и дожидается получения кассового чека (вызов wait (receipt)). Кассир осуществляет прием платежей, ожидая сигнала о платеже, принимая деньги, а затем сообщая об этом. Здесь следует постараться избежать ряда программных ошибок. Если вызов signal (payment) выполняется непосредственно перед вызовом pay (), то клиент может оказаться прерванным в этот момент, и кассир будет пытаться принять не переданные деньги. Еще более серьезная ошибка происходит при обмене строк signal (payment) и wait (receipt). Это может привести к взаимоблокировке всех клиентов и кассира их операциями wait. · Координация действий кассира и парикмахера. В целях экономии средств парикмахерская не нанимает отдельного кассира. Это действие выполняет парикмахер, когда не стрижет клиента. Для того чтобы обеспечить выполнение парикмахером в один момент времени только одной функции, используется семафор coord.
Листинг. Неполное решение задачи о парикмахерской. semaphore max_capacity = 20; semaphore sofa = 4; semaphore barber_chair = 3; semaphore coord = 3; semaphore cust_ready = 0, finished - 0, leave_b_chair = 0, payment = 0, receipt = 0; void customer() { wait(max_capacity); enter_shop(); wait(sofa); sit_on_sofa(); wait(barber_chair); get_up_from_sofa(); signal(sofa); sit in barber_chair(); signal(cust_ready); wait(finished); leave_barber_chair(); signal(leave_b_chair); pay(); signal(payment); wait(receipt); exit_shop(); signal(max_capacity); } void barber() { while(true) { wait(cust_ready); wait(coord); cut_hair(); signal(coord); signal(finished); wait(leave_b_chair); signal(barber_chair); } } void cashier() { while(true) { wait(payment); wait(coord); accept_pay(); signal(coord); signal (receipt); } } void main() { parbegin(customer,... [50 раз]..., customer, barber, barber, barber, cashier); }
Процесс кассира можно устранить, внеся функцию оплаты в процедуру парикмахера. Каждый парикмахер будет последовательно стричь и принимать плату. Однако при наличии одного кассового аппарата необходимо ограничить доступ к функции accept_pay() одним парикмахером в каждый момент времени. Этого можно добиться, рассматривая функцию как критический раздел и оградив ее соответствующим семафором.
|