Проблемы синхронизации в ос. Проблема спящего брадобрея

Проблемы синхронизации в ос. Проблема спящего брадобрея

Литература по операционным системам содержит множество интересных проблем, которые широко обсуждались и анализировались с применением различных методов синхронизации. В этом разделе мы рассмотрим три наиболее известные проблемы.

Проблема обедающих философов

В 1965 году Дейкстра сформулировал и решил проблему синхронизации, названную им проблемой обедающих философов. С тех пор каждый, кто изобретал еще один новый примитив синхронизации, считал своим долгом продемонстрировать достоинства нового примитива на примере проблемы обедающих философов. Проблему можно сформулировать следующим образом: пять философов сидят за круглым столом, и у каждого есть тарелка со спагетти. Спагетти настолько скользкие, что каждому философу нужно две вилки, чтобы с ними управиться. Между каждыми двумя тарелками лежит одна вилка.

Жизнь философа состоит из чередующихся периодов поглощения пищи и размышлений. (Разумеется, это абстракция, даже применительно к философам, но остальные процессы жизнедеятельности для нашей задачи несущественны.) Когда философ голоден, он пытается получить две вилки, левую и правую, в любом порядке. Если ему удалось получить две вилки, он некоторое время ест, затем кладет вилки обратно и продолжает размышления. Вопрос состоит в следующем: можно ли написать алгоритм, который моделирует эти действия для каждого философа и никогда не застревает? (Кое-кто считает, что необходимость двух вилок выглядит несколько искусственно. Возможно, нам следует заменить итальянскую пищу блюдами китайской кухни, спагетти - рисом, а вилки - соответствующими палочками.)

Можно изменить программу так, чтобы после получения левой вилки проверялась доступность правой. Если правая вилка недоступна, философ отдает левую обратно, ждет некоторое время и повторяет весь процесс. Этот подход также не будет работать, хотя и по другой причине. Если не повезет, все пять философов могут начать процесс одновременно, взять левую вилку, обнаружить отсутствие правой, положить левую обратно на стол, одновременно взять левую вилку, и так до бесконечности. Ситуация, в которой все программы продолжают работать сколь угодно долго, но не могут добиться хоть какого-то прогресса, называется зависанием процесса (по-английски starvation, буквально «умирание от голода». Этот

Термин применяется даже в том случае, когда проблема возникает не в итальянском или китайском ресторане, а на компьютерах).

Вы можете подумать: «Если философы будут размышлять в течение некоторого случайно выбранного промежутка времени после неудачной попытки взять правую вилку, вероятность того, что все процессы будут продолжать топтаться на месте хотя бы в течение часа, невелика». Это правильно, и для большинства приложений повторение попытки спустя некоторое время не является проблемой. Например, в локальной сети Ethernet в ситуации, когда два компьютера посылают пакеты одновременно, каждый должен подождать случайно заданное время и повторить попытку - на практике это решение хорошо работает. Тем не менее в некоторых приложениях предпочтительным является другое решение, работающее всегда и не зависящее от случайных чисел (например, в приложении для обеспечения безопасности на атомных электростанциях).

Внести улучшение, исключающее взаимоблокировку и зависание процесса: защитить пять операторов, следующих за запросом think, бинарным семафором. Тогда философ должен будет выполнить операцию Down на переменной mutex прежде, чем потянуться к вилкам. А после возврата вилок на место ему следует выполнить операцию Up на переменной mutex. С теоретической точки зрения решение вполне подходит. С точки зрения практики возникают проблемы с эффективностью: в каждый момент времени может есть спагетти только один философ. Но вилок пять, поэтому необходимо разрешить есть в каждый момент времени двум философам.

Решение, исключает взаимоблокировку и позволяет реализовать максимально возможный параллелизм для любого числа философов. Здесь используется массив state для отслеживания душевного состояния каждого философа: он либо ест, либо размышляет, либо голодает (пытаясь получить вилки). Философ может начать есть, только если ни один из его соседей не ест. Соседи философа с номером i определяются макросами LEFT и RIGHT (то есть если i = 2, то LEFT=

Проблема читателей и писателей

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

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

Проблема спящего брадобрея

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

В предлагаемом решении используются три семафора: customers, для подсчета ожидающих посетителей (клиент, сидящий в кресле брадобрея, не учитывается - он уже не ждет); barbers, количество брадобреев (0 или 1), простаивающих в ожидании клиента, и mutex для реализации взаимного исключения. Также используется переменная waiting, предназначенная для подсчета ожидающих посетителей.

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

Когда брадобрей приходит утром на работу, он выполняет процедуру barber, блокируясь на семафоре customers, поскольку значение семафора равно 0. Затем брадобрей засыпает, и спит, пока не придет первый клиент.

Приходя в парикмахерскую, посетитель выполняет процедуру customer, запрашивая доступ к mutex для входа в критическую область. Если вслед за ним появится еще один посетитель, ему не удастся что-либо сделать, пока первый посетитель не освободит доступ к mutex. Затем посетитель проверяет наличие свободных стульев, в случае неудачи освобождает доступ к mutex и уходит.

Если свободный стул есть, посетитель увеличивает значение целочисленной переменной waiting. Затем он выполняет процедуру up на семафоре customers, тем

Самым активизируя поток брадобрея. В этот момент оба - посетитель и брадобрей - активны. Когда посетитель освобождает доступ к mutex, брадобрей захватывает его, проделывает некоторые служебные операции и начинает стричь клиента.

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

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

Проблема

Аналогия основана на гипотетической парикмахерской с одним парикмахером. У парикмахера есть одно рабочее место и приемная со многими стульями. Когда парикмахер заканчивает подстригать клиента, он отпускает клиента и затем идет в приёмную, чтобы посмотреть, есть ли ждущие клиенты. Если есть, он приглашает одного из них и стрижет его. Если ждущих клиентов нет, он возвращается к своему креслу и спит в нем.

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

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

Проблема спящего парикмахера часто приписывается Эдсгеру Дейкстра (1965), одному из пионеров информатики.

Решение

Доступно множество возможных решений. Основной элемент каждого - mutex , который гарантирует, что изменить состояние (state ) может только один из участников. Парикмахер должен захватить это mutex исключение, прежде чем проверить клиентов, и освободить его, когда он начинает или спать, или работать. Клиент должен захватить mutex, прежде чем войти в магазин, и освободить его, как только он займет место или в приемной, или у парикмахера. Это устраняет обе проблемы, упомянутые в предыдущей секции. Семафоры также обязаны указывать на состояние системы. Например, можно было бы сохранить число людей в приемной.

У варианта с несколькими парикмахерами есть дополнительная сложность координирования нескольких парикмахеров среди ждущих клиентов.

См. также

  • Проблема курильщиков

Ссылки

  • Modern Operating Systems (2nd Edition) by Andrew S. Tanenbaum (ISBN 0-13-031358-0)
  • The Little Book of Semaphores by Allen B. Downey, http://greenteapress.com/semaphores
  • Cooperating sequential processes by E.W. Dijkstra. Technical Report EWD-123, 1965, Technological University, Eindhoven, The Netherlands.

Wikimedia Foundation . 2010 .

Действие еще одной классической проблемной ситуации межпроцессного взаимодействия разворачивается в парикмахерской. В парикмахерской есть один брадобрей, его кресло и n стульев для посетителей. Если желающих воспользоваться его услугами нет, брадобрей сидит в своем кресле и спит. Если в парикмахерскую приходит клиент, он должен разбудить брадобрея. Если клиент приходит и видит, что брадобрей занят, он либо садится на стул (если есть место), либо уходит (если места нет). Необходимо запрограммировать брадобрея и посетите­лей так, чтобы избежать состояния состязания. У этой задачи существует много аналогов в сфере массового обслуживания, например информационная служба, обрабатывающая одновременно ограниченное количество запросов, с компьютеризированной системой ожидания для запросов.

В предлагаемом решении используются три семафора: customers, для подсчета ожидающих посетителей (клиент, сидящий в кресле брадобрея, не учитывается); barbers, количество брадобреев (0 или 1), простаивающих в ожидании клиента, и mutex для реализации взаимного исключения. Также используется переменная waiting, предназначенная для подсчета ожидающих посетителей.

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

Планирование процессов. Задачи алгоритмов планирования.

Когда компьютер работает в многозадачном режиме, на нем могут быть активны­ми несколько процессов, пытающихся одновременно получить доступ к процессору. Эта ситуация возникает при наличии двух и более процессов в состоянии готовности. Если доступен только один процессор, необходимо выбирать между процессами. Отвечающая за это часть операционной системы называется планировщиком , а используемый алгоритм - алгоритмом планирования .

Планирование - это разделение вычислительных ресурсов системы между процессами и потоками.

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

данные и т. д.

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

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

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

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

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

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

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

1. Системы пакетной обработки данных.

2. Интерактивные системы.

3. Системы реального времени.

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

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

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

Задачи алгоритмов планирования.

Чтобы разработать алгоритм планирования, необходимо иметь представление о том, что должен делать хороший алгоритм. Некоторые задачи зависят от среды (системы пакетной обработки, интерактивные или реального времени), но есть задачи, одинаковые во всех системах. Список задач представлен в таблице.

Планирование в системах пакетной обработки данных.

«Первым пришел - первым обслужен»

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

Основным преимуществом этого алгоритма является то, что его легко понять и столь же легко программировать.

Недостатком является абсолютная неоптимизированность планирования.

«Кратчайшая задача - первая»

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

Преимущество алгоритма заключается в оптимизации задачи.

Недостатком является то, что эта схема работает лишь в случае одновременного наличия задач.


Похожая информация.


1.cpp
bradobrej1.dsp
bradobrej1.dsw
bradobrej1.ncb
bradobrej1.opt
bradobrej1.plg
1.obj
bradobrej1.exe
bradobrej1.ilk
bradobrej1.pch
bradobrej1.pdb
vc60.idb
vc60.pdb
bradobrej1.exe
2.cpp
bradobrej2.dsp
bradobrej2.dsw
bradobrej2.ncb
bradobrej2.opt
bradobrej2.plg
2.obj
bradobrej2.exe
bradobrej2.ilk
bradobrej2.pch
bradobrej2.pdb
vc60.idb
vc60.pdb
bradobrej2.exe
162kb. 05.09.2008 12:01


    Смотрите также:

Лр1.doc

Операционные системы.


Лабораторная работа №1

Тема: Подсистема управления процессами. Задача о спящем парикмахере.

Цель: Ознакомится с основными методами которые применяются в подсистемах управления процессами.

Материал для предварительного изучения:

1. Понятие и организация процессов.

2. Реализация процессов в ОС Windows.

3. Средства языка С для работы с процессами.

Теоретический материал.

Процессам часто бывает необходимо взаимодействовать между собой. Например, в конвейере ядра выходные данные первого процесса должны передаваться второ-му и т. д. по цепочке. Поэтому возникает необходимость в правильно организованном взаимодей-ствии между процессами (IPC, interprocess communication), по возможности не использующим прерываний.

Проблема разбивается на три пункта. Первый мы уже упомянули: передача информации от одного процесса другому. Второй связан с контролем над дея-тельностью процессов: как гарантировать, что два процесса не пересекутся в кри-тических ситуациях (представьте себе два процесса, каждый из которых пытается завладеть последним мегабайтом памяти). Третий касается согласования действий процессов: если процесс А должен поставлять данные, а процесс В выводить их на печать, то процесс В должен подождать и не начинать печатать, пока не поступят данные от процесса А .

Важно понимать, что два из трех описанных пунктов в равной мере относятся и к потокам. Первый - передача информации - в случае потоков проблемой не является, поскольку у потоков общее адресное пространство (передача информа-ции между потоками с разным адресным пространством уже является проблемой передачи информации между процессами). Остальные два с тем же успехом касаться потоков: те же проблемы, и те же решения. Мы будем рассматривать эти ситуации в контексте процессов, но имейте в виду, что эти же рассуждения приме-ры и для потоков.

^ 1. Состояние состязания.

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

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

Представьте, что каталог спулера состоит из большого числа сегментов, прону-мерованных 0, 1, 2, ..., в каждом их которых может храниться имя файла. Также есть две совместно используемые переменные: out, указывающая на следующий файл для печати, и in, указывающая на следующий свободный сегмент. Эти две переменные можно хранить в одном файле (состоящем из двух слов), доступном всем процессам. Пусть в данный момент сегменты с 0 по 3 пусты (эти файлы уже напечатаны), а сегменты с 4 по 6 заняты (эти файлы ждут своей очереди на печать). Более или менее одновременно процессы А и В решают поставить файл в очередь на печать. Описанная ситуация схематически изображена на рис. 2.14.

В соответствии с законом Мерфи (он звучит примерно так: «Если что-то плохое может случиться, оно непременно случится») возможна следующая ситуация. Процесс А считывает значение (7) переменной in и сохраняет его в локальной переменной next_free_slot. После этого происходит прерывание по таймеру, и процессор переключается на процесс В. Процесс В, в свою очередь, считывает значение переменнойin и сохраняет его (опять 7) в своей локальной переменной next_free_slot. В данный момент оба процесса считают, что следующий свободный сегмент седьмой. Процесс В сохраняет в каталоге спулера имя файла и заменяет значение in на 8 затем продолжает заниматься своими задачами, не связанными с печатью. Наконец управление переходит к процессу А , и он продолжает с того места на котором остановился. Он обращается к переменной next_freе_ slot, считывает ее значение и записывает в седьмой сегмент имя файла (разумеется, удаляя при этом имя файла, записанное туда процессом В). Затем он заменяет значение in на 8 (next_free_slot +1 = 8). Структура каталога спулера не нарушена, так что демон печати не заподозрит ничего плохого, но файл процесса В не будет напе-чатан.

Ситуации, в ко-торых два (и более) процесса считывают или записывают данные одновременно и конечный результат зависит от того, какой из них был первым, называются состояниями состязания.

Критические области.

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

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

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

1. Невозможна ситуация, в которой процесс вечно ждет попадания в крити-ческую область.

2. Два процесса не должны одновременно находиться в критических обла-стях.

3. В программе не должно быть предположений о скорости или количестве процессоров.

4. Процесс, находящийся вне критической области, не может блокировать дру-гие процессы.

В абстрактном виде требуемое поведение процессов представлено на рис. 2.15. Процесс А попадает в критическую область в момент времени Т 1 . Чуть позже, в мо-мент времени Т 2 , процесс В пытается попасть в критическую область, но ему это не удается, поскольку в критической области уже находится процесс А, а два процесса не должны одновременно находиться в критических областях. Поэто-му процесс В временно приостанавливается, до наступления момента времени Т 3 , когда процесс А выходит из критической области. В момент времени Т 4 процесс В также покидает критическую область, и мы возвращаемся в исходное состояние, когда ни одного процесса в критической области не было.


Семафоры.

В 1965 году Дейкстра (Е. W. Dijkstra) предложил использовать целую перемен-ную для подсчета сигналов запуска, сохраненных на будущее. Им был пред-ложен новый тип переменных, так называемые семафоры , значение которых мо-жет быть нулем (в случае отсутствия сохраненных сигналов активизации) или некоторым положительным числом, соответствующим количеству отложенных активизирующих сигналов.

Дейкстра предложил две операции, down и up (обобщения sleep и wakeup ). Опе-рация down сравнивает значение семафора с нулем. Если значение семафора боль-ше нуля, операция down уменьшает его (то есть расходует один из сохраненных сиг-налов активации) и просто возвращает управление. Если значение семафора равно нулю, процедура down не возвращает управление процессу, а процесс переводится в состояние ожидания. Все операции проверки значения семафора, его изменения и перевода процесса в состояние ожидания выполняются как единое и неделимое элементарноедействие. Тем самым гарантируется, что после начала операции ни один процесс не получит доступа к семафору до окончания или блокирования операции. Элементарность операции чрезвычайно важна для разрешения пробле-мы синхронизации и предотвращения состояния состязания.

Операция up увеличивает значение семафора. Если с этим семафором связаны один или несколько ожидающих процессов, которые не могут завершить более раннюю операцию down, один из них выбирается системой (например, случайным образом) и ему разрешается завершить свою операцию down. Таким образом, послеоперации up примененной к семафору, связанному с несколькими ожидающими процессами, значение семафора так иостанется равным 0, но число ожидающих процессов уменьшится на единицу. Операция увеличения значения семафора и активизации процесса тоже неделима. Ни один процесс не может быть блокирован во время выполнения операции up , как ни один процесс не мог быть блокирован во время выполнения операции wakeup в предыдущей модели.

В оригинале Дейкстра использовал вместо down иup обозначения Р и V соответственно. Мы не будем в дальнейшем использовать оригинальные обозначения поскольку тем, кто не знает датского языка, эти обозначения ничего не говорят (да и тем, кто знает язык, говорят немного). Впервые обозначения down иup появились в языке Algol 68.

Решение проблемы производителя и потребителя с помощью семафоров.

Как показано в листинге 2.4, проблему потерянных сигналов запуска можно ре-шить с помощью семафоров. Очень важно, чтобы они были реализованы неде-лимым образом. Стандартным способом является реализация операций down и up в виде системных запросов, с запретом операционной системой всех прерываний на период проверки семафора, изменения его значения и возможного перевода про-цесса в состояние ожидания. Поскольку для выполнения всех этих действий тре-буется всего лишь несколько команд процессора, запрет прерываний не приносит никакого вреда. Если используются несколько процессоров, каждый семафор необ-ходимо защитить переменной блокировки с использованием команды TSL, чтобы гарантировать одновременное обращение к семафору только одного процессора. Необходимо понимать, что использование команды TSL принципиально отличает-ся от активного ожидания, при котором производитель или потребитель ждут на-полнения или опустошения буфера. Операция с семафором займет несколько мик-росекунд, тогда как активное ожидание может затянуться на существенно больший промежуток времени.

Листинг 2.4.Проблема производителя и потребителя с семафорами

#define N 100 /* количество сегментов в буфере */

Typedef int semaphore; /* семафоры - особый вид целочисленных переменных */ semaphore mutex =1; /* контроль доступа в критическую область */

Semaphore empty = N; /* число пустых сегментов буфера /

Semaphore full = О; /* число полных сегментов буфера */

voidproducer(void)

While(TRUE)

{ /* TRUE - константа, равная 1*/

Item = protiuce_item (); /* создать данные, помещаемые в буфер */

Down(&empty); /* уменьшить счетчик пустых сегментов буфера */

Down(&mutex): /* вход в критическую область */

Insert_item(item); /* поместить в буфер новый элемент */

Up(&mutex): /* выход из критической области */

Up(&ful1); /* увеличить счетчик полных сегментов буфера */

Void consumer(void)

{ /* бесконечный цикл */

Down(&full); /* уменьшить числа полных сегментов буфера */

Down(&mutex); /* вход в критическую область */

Item = remove_item(); /* удалить элемент из буфера */

Up(&mutex); /* выход из критической области */

Up(&empty): /* увеличить счетчик пустых сегментов буфера */

Consume_item(item): /* обработка элемента */

В представленном решении используются три семафора: один для подсчета за-полненных сегментов буфера (full), другой для подсчета пустых сегментов (empty), а третий предназначен для исключения одновременного доступа к буферу произ-водителя и потребителя (mutex). Значение счетчика full исходно равно нулю, счет-чик empty равен числу сегментов в буфере, a mutex равен 1. Семафоры, исходное значение которых равно 1, используемые для исключения одновременного нахож-дения в критической области двух процессов, называются двоичными семафора-ми. Взаимное исключение обеспечивается, если каждый процесс выполняет опе-рацию down перед входом в критическую область и up после выхода из нее.

Теперь, когда у нас есть примитивы межпроцессного взаимодействия, вернем-ся к последовательности прерываний, показанной в табл. 2.2. В системах, исполь-зующих семафоры, естественным способом скрыть прерывание будет связать с каждым устройством ввода-вывода семафор, исходно равный нулю. Сразу после запуска устройства ввода-вывода управляющий процесс выполняет операцию down на соответствующем семафоре, тем самым входя в состояние блокировки. В случае прерывания обработчик прерывания выполняет up на соответствующем семафоре, переводя процесс в состояние готовности. В такой модели пятый шаг в табл. 2.2 заключается в выполнении up на семафоре устройства, чтобы следующим шагом планировщик смог запустить программу, управляющую устройством. Разумеет-ся, если в этот момент несколько процессов находятся в состоянии готовности, планировщик может выбрать другой, более значимый процесс.

В примере, представленном в листинге 2.4, семафоры использовались двумя различными способами. Это различие достаточно значимо, чтобы сказать о нем особо. Семафор mutex используется для реализации взаимного исключения, тоесть для исключения одновременного обращения к буферу и связанным переменным двух процессов.

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

^ Постановка задачи:

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

Согласно данной задаче необходимо определить элементы который будут запрограммированы отдельными процессами, разработать алгоритм и программно его реализовать.

В решении предлагается использовать три семафора:

customers, для подсчета ожидающих посетителей (клиент, сидящий в кресле брадобрея, не учитывается – он уже не ждет);

barbers, количество брадобреев (0 или 1), простаивающих в ожидании клиента;

mutex для реализации взаимного исключения.

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

1. Тема и цель работы.

2. Задание на лабораторную работу.

3. Алгоритм программы.

4. Полученные результаты.

5. Выводы по работе с анализом реализованной модели взаимодействия процессов.


Важной и часто встречающейся задачей, решение которой требует синхронизации, является задача «Читатели - писатели». Эта задача имеет много вариантов. Определить ее можно следующим образом. Имеются данные, совместно используемые рядом процессов. Данные могут находиться в файле в блоке основной памяти или даже в регистрах процессора. Имеются несколько процессов, которые только читают эти данные (Читатели), и несколько других, которые только записывают данные (Писатели). При этом должны удовлетворяться следующие условия.- Любое число читателей могут одновременно читать файл.- Записывать информацию в файл в определенный момент времени может только один Писатель.- Когда Писатель записывает информацию в файл, ни один Читатель не может его читать. Пример использования - работа с библиотечным каталогом. Другим типичным примером служит система автоматизированной продажи билетов. Процессы «Читатели» обеспечивают нас справочной информацией о наличии свободных билетов на тот или иной рейс. Процессы «Писатели» запускают с пульта кассира, когда он оформляет для нас тот или иной билет. Имеется большое количество как «Читателей», так и «Писателей». Наиболее характерная область использования этой задачи в вычислительной системе - при построении систем управления файлами. Два класса процессов имеют доступ к некоторому ресурсу (области памяти, файлам). «Читатели» - это процессы, которые могут параллельно считывать информацию из некоторой общей области памяти, являющейся критическим ресурсом. «Писатели» - это процессы, записывающие информацию в эту область памяти, исключая при этом и друг друга и процессы «Читатели». Широко распространены следующие условия: 1.Приоритетное чтение: Устанавливается приоритет в использование критического ресурса процесса Читатели. Это означает, что если хотя бы один Читатель пользуется ресурсом, то он закрыт для использования всем Писателям и доступен для использования всем Читателям. При появлении запроса от Писателя необходимо закрыть дальнейший доступ всем тем процессам Читателям, которые выдадут запрос на критический ресурс после него.

15 Задача о спящем брадобрее. Задача о спящем брадобрее. Действие еще одной классической проблемной ситуации межпроцесс-ного взаимодействия разворачивается в парикмахерской. В парикмахерской есть один брадобрей, его кресло и n стульев для посетителей. Если желаю-щих воспользоваться его услугами нет, брадобрей сидит в своем кресле и спит. Если в парикмахерскую приходит клиент, он должен разбудить брадо-брея. Если клиент приходит и видит, что брадобрей занят, он либо садится на стул (если есть место), либо уходит (если места нет). Необходимо запро-граммировать брадобрея и посетителей так, чтобы избежать состояния состя-зания. В решении можно использовать три семафора: customers , для подсчета ожидающих посетителей (клиент, сидящий в кресле брадобрея, не учитыва-ется - он уже не ждет); barbers , количество брадобреев 0 или 1), простаи-вающих в ожидании клиента, и mutex для реализации взаимного исключения. Также используется переменная waiting , предназначенная для подсчета ожи-дающих посетителей. Она является копией переменной customers . Присутст-вие в программе этой переменной связано с тем фактом, что прочитать теку-щее значение семафора невозможно. В этом решении посетитель, заглядывающий в парикмахерскую, дол-жен сосчитать количество ожидающих посетителей. Если посетителей мень-ше, чем стульев, новый посетитель остается, в противном случае он уходит. Когда брадобрей приходит утром на работу, он выполняет процедуру barber , блокируясь на семафоре customers , поскольку значение семафора равно 0. Затем брадобрей засыпает, как показано на рис., и спит, пока не при-дет первый клиент. Приходя в парикмахерскую, посетитель выполняет про-цедуру customer , запрашивая доступ к mutex для входа в критическую об-ласть. Если вслед за ним появится еще один посетитель, ему не удастся что-либо сделать, пока первый посетитель не освободит доступ к mutex . Затем посетитель проверяет наличие свободных стульев, в случае неудачи освобо-ждает доступ к mutex и уходит. Если свободный стул есть, посетитель увели-чивает значение целочисленной переменной waiting . Затем он выполняет процедуру up на семафоре customers , тем самым активизируя поток брадо-брея. В этот момент оба - посетитель и брадобрей - активны. Когда посе-титель освобождает доступ к mutex , брадобрей захватывает его, проделывает некоторые служебные операции и начинает стричь клиента. По окончании 7 стрижки посетитель выходит из процедуры и покидает парикмахерскую. В отличие от предыдущих программ, цикла посетителя нет, поскольку каждого посетителя стригут только один раз. Цикл брадобрея существует, и брадо-брей пытается найти следующего посетителя. Если ему это удается, он стри-жет следующего посетителя, в противном случае брадобрей засыпает. Стоит отметить, что, несмотря на отсутствие передачи данных в проблеме читате-лей и писателей и в проблеме спящего брадобрея, обе эти проблемы относят-ся к проблемам межпроцессного взаимодействия, поскольку требуют син-хронизации нескольких процессов.


16 Алгоритмы планирования процессов.

Алгоритмы планирования процессов

Планирование процессов включает в себя решение следующих задач:

1. определение момента времени для смены выполняемого процесса;

2. выбор процесса на выполнение из очереди готовых процессов;

3. переключение контекстов "старого" и "нового" процессов.

FCFS - Простейшим алгоритмом планирования является алгоритм, который принято обозначать аббревиатурой FCFS по первым буквам его английского названия (первым пришел, первым обслужен). Представим себе, что процессы, находящиеся в состоянии готовность, выстроены в очередь. Когда процесс переходит в состояние готовность, он, а точнее, ссылка на его PCB помещается в конец этой очереди. Выбор нового процесса для исполнения осуществляется из начала очереди с удалением оттуда ссылки на его PCB. Очередь подобного типа имеет в программировании специальное наименование – FIFO (первым вошел, первым вышел). Такой алгоритм выбора процесса осуществляет невытесняющее планирование. Преимуществом алгоритма FCFS является легкость его реализации, но в то же время он имеет и много недостатков. Round Robin (RR) Модификацией алгоритма FCFS является алгоритм, получивший название Round Robin (Round Robin – это вид детской карусели в США) или сокращенно RR. По сути дела, это тот же самый алгоритм, только реализованный в режиме вытесняющего планирования. Можно представить себе все множество готовых процессов организованным циклически – процессы сидят на карусели. Карусель вращается так, что каждый процесс находится около процессора небольшой фиксированный квант времени, обычно 10 – 100 миллисекунд. Пока процесс находится рядом с процессором, он получает процессор в свое распоряжение и может исполняться. Реализуется такой алгоритм так же, как и предыдущий, с помощью организации процессов, находящихся в состоянии готовность, в очередь FIFO. Планировщик выбирает для очередного исполнения процесс, расположенный в начале очереди, и устанавливает таймер для генерации прерывания по истечении определенного кванта времени. При выполнении процесса возможны два варианта. 1.Время непрерывного использования процессора, необходимое процессу (остаток текущего CPU burst), меньше или равно продолжительности кванта времени. Тогда процесс по своей воле освобождает процессор до истечения кванта времени, на исполнение поступает новый процесс из начала очереди, и таймер начинает отсчет кванта заново. 2.Продолжительность остатка текущего CPU burst процесса больше, чем квант времени. Тогда по истечении этого кванта процесс прерывается таймером и помещается в конец очереди процессов, готовых к исполнению, а процессор выделяется для использования процессу, находящемуся в ее начале. На производительность алгоритма RR сильно влияет величина кванта времени. При очень больших величинах кванта времени, когда каждый процесс успевает завершить свой CPU burst до возникновения прерывания по времени, алгоритм RR вырождается в алгоритм FCFS. При очень малых величинах создается иллюзия того, что каждый из n процессов работает на собственном виртуальном процессоре с производительностью ~ 1/n от производительности реального процессора.Shortest-Job-First (SJF) . Гарантированное планирование. При рассмотрении алгоритмов FCFS и RR мы видели, насколько существенным для них является порядок расположения процессов в очереди процессов, готовых к исполнению. Если короткие задачи расположены в очереди ближе к ее началу, то общая производительность этих алгоритмов значительно возрастает. Если бы мы знали время следующих CPU burst для процессов, находящихся в состоянии готовность, то могли бы выбрать для исполнения не процесс из начала очереди, а процесс с минимальной длительностью CPU burst . Если же таких процессов два или больше, то для выбора одного из них можно использовать уже известный нам алгоритм FCFS . Квантование времени при этом не применяется. Описанный алгоритм получил название "кратчайшая работа первой" или Shortest Job First (SJF ). SJF-алгоритм краткосрочного планирования может быть как вытесняющим , так и невытесняющим . При невытесняющем SJF -планировании процессор предоставляется избранному процессу на все необходимое ему время, независимо от событий, происходящих в вычислительной системе. При вытесняющем SJF -планировании учитывается появление новых процессов в очереди готовых к исполнению (из числа вновь родившихся или разблокированных) во время работы выбранного процесса. Гарантированное планирование -При интерактивной работе N пользователей в вычислительной системе можно применить алгоритм планирования, который гарантирует, что каждый из пользователей будет иметь в своем распоряжении ~1/N часть процессорного времени. Пронумеруем всех пользователей от 1 до N. Для каждого пользователя с номером i введем две величины: T i – время нахождения пользователя в системе или, другими словами, длительность сеанса его общения с машиной и τ i – суммарное процессорное время уже выделенное всем его процессам в течение сеанса. Справедливым для пользователя было бы получение T i /N процессорного времени. Если τ i <>T i /N то система явно благоволит к пользователю с номером i. Вычислим для процессов каждого пользователя значение коэффициента справедливости τ i N/T i и будем предоставлять очередной квант времени готовому процессу с наименьшей величиной этого отношения. Предложенный алгоритм называют алгоритмом гарантированного планирования. К недостаткам этого алгоритма можно отнести невозможность предугадать поведение пользователей. Если некоторый пользователь отправится на пару часов пообедать и поспать, не прерывая сеанса работы, то по возвращении его процессы будут получать неоправданно много процессорного времени.

Приоритетное планирование. Алгоритмы SJF и гарантированного планирования представляют собой частные случаи приоритетного планирования . При приоритетном планировании каждому процессу присваивается определенное числовое значение – приоритет , в соответствии с которым ему выделяется процессор. Процессы с одинаковыми приоритетами планируются в порядке FCFS . Для алгоритма SJF в качестве такого приоритета выступает оценка продолжительности следующего CPU burst . Чем меньше значение этой оценки, тем более высокий приоритет имеет процесс. Для алгоритма гарантированного планирования приоритетом служит вычисленный коэффициент справедливости. Чем он меньше, тем больше у процесса приоритет . Алгоритмы назначения приоритетов процессов могут опираться как на внутренние параметры, связанные с происходящим внутри вычислительной системы, так и на внешние по отношению к ней. К внутренним параметрам относятся различные количественные и качественные характеристики процесса такие как: ограничения по времени использования процессора, требования к размеру памяти, число открытых файлов и используемых устройств ввода-вывода, отношение средних продолжительностей I/O burst к CPU burst и т. д. Алгоритмы SJF и гарантированного планирования используют внутренние параметры. В качестве внешних параметров могут выступать важность процесса для достижения каких-либо целей, стоимость оплаченного процессорного времени и другие политические факторы. Высокий внешний приоритет может быть присвоен задаче лектора или того, кто заплатил $100 за работу в течение одного часа. Планирование с использованием приоритетов может быть как вытесняющим , так и невытесняющим . При вытесняющем планировании процесс с более высоким приоритетом , появившийся в очереди готовых процессов, вытесняет исполняющийся процесс с более низким приоритетом . В случае невытесняющего планирования он просто становится в начало очереди готовых процессов. Давайте рассмотрим примеры использования различных режимов приоритетного планирования . Главная проблема приоритетного планирования заключается в том, что при ненадлежащем выборе механизма назначения и изменения приоритетов низкоприоритетные процессы могут не запускаться неопределенно долгое время. Обычно случается одно из двух. Или они все же дожидаются своей очереди на исполнение. Или вычислительную систему приходится выключать, и они теряются. Решение этой проблемы может быть достигнуто с помощью увеличения со временем значения приоритета процесса , находящегося в состоянии готовность.

просмотров