Операционные системы. Управление ресурсами

       

Свойства ресурсов и их представление


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

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

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

Наши ресурсы обладают также свойствами дискретности и ограниченности. Первое означает, что ресурсы распределяются некоторыми неделимыми единицами (не может быть полтора принтера).
Второе - то, что число единиц ресурса всегда небесконечно. (Процессорное время - бесконечно: его достаточно для выполнения любого процесса, и оно может дробиться планировщиком. Реальная память всегда конечна, виртуальная тоже ограничена разрядностью виртуального адреса, а непрерывность или дискретность ее зависит от принятой модели).
Мы будем называть классом ресурса пул идентичных неименованных единиц ресурса. Неименованными мы считаем их в том смысле, что процесс при запросе ресурса не указывает, какую именно единицу из пула он хочет получить, все единицы ресурса одинаковы. Все ресурсы одного класса управляются одним менеджером.
Из определений ОС (как с точки зрения разработчика, так и с точки зрения пользователя), которые мы дали в первой главе, однозначно следует, что процесс ни в коем случае не может самостоятельно завладеть ресурсом - а только через посредство ОС. Для предоставления процессам такой возможности в составе API ОС должны быть системные вызовы типа:
resourceHandle = getResource(class, number [,action] ); releaseResource(resourceHandle);
Первый вызов выделяет процессу number ресурсов из класса class и возвращает манипулятор (handle) выделенного ресурса, который при всех дальнейших операциях процесса с ресурсом служит для идентификации ресурса. Манипулятор каким-то образом адресует дескриптор ресурса. В защищенных системах такой дескриптор располагается в недоступном для процесса адресном пространстве. Манипулятор обычно является номером в системной таблице или списке дескрипторов, и по нему ядро (но не процесс) выбирает требуемый дескриптор ресурса.
Второй вызов открепляет от процесса ранее выделенный ему ресурс. Возможно, форма выделения/освобождения ресурса напомнила вам знакомые операции открытия / закрытия файла - и недаром. Поскольку файлы также являются ресурсами, операции open/close являются частными случаями операций getResource/releaseResource. Как правило, в реальных API ОС нет общих операций выделения/освобождения ресурсов, но для каждого ресурса имеется своя пара операций, отличающаяся от других названием и, возможно, составом параметров.


Третий, необязательный параметр операции getResource задает действия ОС в ситуации, когда выделить ресурс невозможно (не все ОС предоставляют процессам возможности такого выбора). Во-первых (и это действие обычно выполняется по умолчанию), ОС может заблокировать процесс, выдавший запрос, до освобождения требуемого ресурса. Во-вторых, ОС может не блокировать процесс, а вернуть ему отказ - сразу или после некоторой временной выдержки (timeout), в этом случае "умный" процесс может пока заняться другой работой, которую он может выполнить и без этого ресурса, а позже повторить запрос. Как ОС должна реагировать на запрос, который вообще не может быть выполнен (требуемого объема ресурсов просто нет в системе)? По нашему убеждению, такой запрос должен приводить к аварийному завершению выдавшего его процесса. Но если ОС допускает динамическую реконфигурацию ресурсов, то запрос может быть поставлен в очередь в ожидании момента, когда ресурс будет введен в систему. Такие нереализуемые запросы могут составлять серьезную неприятность в работе ОС, так как ресурс может никогда и не быть введен. Для избежания таких запросов целесообразно иметь в составе API вызов, возвращающий общее число ресурсов данного класса. Наконец, при невозможности удовлетворить запрос ОС может потребовать от процесса освободить уже имеющиеся в его распоряжении ресурсы. Если такая возможность имеется, то она может быть очень полезна для развязки тупиков (см. ниже).
Для каждого класса ресурсов ОС должна поддерживать дескриптор класса, в который должны входить:


  • идентификатор класса;
  • общее число единиц в классе;
  • число свободных единиц;
  • таблица единиц ресурса;
  • список процессов, ожидающих ресурс этого класса;
  • точка входа в менеджер класса;
  • и т.д.

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


Содержание раздела