Современные операционные системы

Современные операционные системы
Что такое операционная система / Системные вызовы

Системные вызовы




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

Теперь нужно выбрать между 1) неопределенной обобщенностью («у операционных систем есть системные вызовы для чтения файлов») и 2) какой-нибудь конкретной системой («в UNIX есть системный вызов чтения, имеющий три параметра: в одном из них определяется файл, в другом — куда поместить данные, а в третьем — сколько байтов следует считать»).

Мы выбрали второй подход. Пусть он сложнее, но зато позволяет лучше понять, как на самом деле операционная система выполняет свою работу. Хотя все, что будет рассматриваться, имеет непосредственное отношение к стандарту POSIX (Международный стандарт 9945-1), а следовательно к UNIX, System V, BSD, Linux, MINIX 3 и т. д., у большинства других современных операционных систем имеются системные вызовы, выполняющие аналогичные функции, при некоторых отличиях в деталях. Поскольку фактический механизм осуществления системного вызова существенно зависит от конкретной машины и зачастую должен быть реализован на ассемблере, разработаны библиотеки процедур, позволяющие осуществлять системные вызовы из программ, написанных, например, на языке С.

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

Для того чтобы прояснить механизм системных вызовов, рассмотрим системный вызов чтения — read. Как уже упоминалось выше, он имеет три параметра: первый служит для задания файла, второй указывает на буфер, а третий задает количество байтов, которое нужно прочитать. Как практически все системные вызовы, он осуществляется из программы на языке С с помощью вызова библиотечной процедуры, имя которой совпадает с именем системного вызова: read. Вызов из программы на С может иметь следующий вид: count - read(fd. buffer, nbytes):

Системный вызов (и библиотечная процедура) возвращает количество фактически считанных байтов, которое сохраняется в переменной count. Обычно это значение совпадает со значением параметра nbytes, но может быть и меньше, если, например, в процессе чтения будет достигнут конец файла.

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

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

Компиляторы С и С++ помещают параметры в стек в обратном порядке, следуя исторически сложившейся традиции (чтобы на вершине стека оказался первый параметр функции print/ — строка формата вывода данных). Первый и третий параметры передаются по значению, а второй параметр передается по ссылке, поскольку это адрес буфера (о чем свидетельствует знак &), а не его содержимое. Кекс с кабачком



Полное описание: Системные вызовы




С этим описанием рассматриваются следующие темы:


Системные вызовы для управления файлами
Многие системные вызовы имеют отношение к файловой системе. В этом разделе будут рассмотрены вызовы, работающие с отдельными файлами, а в следующем разделе — те вызовы, которые оперируют каталогами или всей файловой системой в целом. Чтобы прочитать данные из файла или записать их в файл, сначала его необходимо открыть с помощью системного вызова open. Для данного вызова необходимо указать имя открываемого файла (с указанием абсолютного пути либо пути относительно рабочего каталога) и код ORDONL ... Читать

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

Библиотечная процедура
Библиотечная процедура, возможно написанная на ассемблере, обычно помещает номер системного вызова туда, где его ожидает операционная система, например в регистр (шаг 5). Затем она выполняет команду TRAP для переключения из пользовательского режима в режим ядра, и выполнение продолжается с фиксированного адреса, находящегося внутри ядра операционной системы (шаг 6). Фактически команда TRAP очень похожа на команду вызова процедуры, в том смысле, что следующая за ней команда берется из удаленного ... Читать

Разные системные вызовы
Помимо описанных выше, существуют также и другие разновидности системных вызовов. Здесь будут рассмотрены только четыре из них. Системный вызов chdir изменяет текущий рабочий каталог. После вызова chdi г С"/usr/ast/test"): при открытии файла xyz будет открыт файл /usr/ast/test/xyz. Использование понятия рабочего каталога избавляет от необходимости постоянно набирать длинные абсолютные пути файлов.

Системные вызовы для управления процессами
Первая группа вызовов в табл. 1.1 предназначена для управления процессами. Начнем рассмотрение системного вызова fork. Вызов fork является единственным существующим в POSIX способом создания нового процесса. Он создает точную копию исходного процесса, включая все дескрипторы файлов, регистры и т. п. После выполнения вызова fork исходный процесс и его копия (родительский и дочерний процессы) выполняются независимо друг от друга. На момент разветвления все их соответствующие переменные имеют одина ... Читать