ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 24.12.2021

Просмотров: 12215

Скачиваний: 10

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Примеры операционных систем 493

ны. («Сборка мусора» — это автоматическое удаление неиспользуемых структур
данных.) «Куча» в NT сходна с функцией

 malloc

 в системах UNIX, но в NT, в отли-

чие от UNIX, может быть несколько независимых «куч».

Примеры виртуального ввода-вывода

Основной задачей любой операционной системы является предоставление служб

для пользовательских программ. Главным образом, это службы ввода-вывода для
чтения и записи файлов. И UNIX, и NT предлагают широкий спектр служб ввода-

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

Виртуальный ввод-вывод в системе UNIX

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

стемы файлов. Обычный файл представляет собой линейную последовательность
8-битных байтов

1

 от 0 до максимум 2

32

-1 байтов. Сама операционная система не

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

С каждым открытым файлом связан указатель на следующий байт, который

нужно считать или записать. Системные вызовы

 read

 и

 write

 считывают и записы-

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

ступ к файлам, когда указатель файла устанавливается на определенное значение.

Кроме обычных файлов, система поддерживает специальные файлы, которые

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

Основные системные вызовы для файлов в UNIX приведены в табл. 6.9. Вызов

creat

 (без

 е

 на конце) используется для создания нового файла. В настоящее время

он не является обязательным, поскольку вызов

 open

 тоже может создавать новый

файл. Вызов

 unlink

 удаляет файл (предполагается, что файл находится только в од-

ной директории).

Вызов

 open

 используется для открытия существующих файлов, а также для

создания новых. Флаг

 mode

 сообщает, как его открыть (для чтения, для записи

и т. д.). Вызов возвращает небольшое целое число, которое называется дескрипто-

ром файла. Дескриптор файла определяет файл в последующих вызовах. Сам про-

1

 Для многих сейчас слова про 8-битные байты могут показаться странными, однако на самом деле рань-

ше байт мог быть и 5-битным, и 7-битным, и 8-битным. Теперь мы по умолчанию считаем байт состо-
ящим из 8 битов. —

 Примеч. научн. ред.


background image

4 9 4

 Глава 6. Уровень операционной системы

цесс ввода-вывода осуществляется с помощью процедур

 read

 и

 write,

 каждая из

которых содержит дескриптор файла (он указывает, какой файл использовать),
буфер для данных и число байтов, которое сообщает, какое количество данных
нужно передать. Вызов

 Iseek

 используется для перемещения указателя файла, что

делает возможным случайный доступ к файлам.

Stat

 выдает информацию о файле (размер, время последнего доступа, имя вла-

дельца и т. п.).

 Chmod

 изменяет режим защиты файла (например, разрешает или,

наоборот, запрещает каким-нибудь пользователям читать его). Наконец,

 fcntl

 выпол-

няет различные действия над файлами, например блокирование и разблокирование.

Таблица 6.9.

 Основные системные вызовы UNIX

Системный вызов Значение

creat(name, mode) Создает файл;

 mode

 определяет тип защиты

unlink(name) Удаляет файл (предполагается, что есть только 1 связь)
open(name, mode) Открывает или создает файл и возвращает дескриптор файла
close(fd) Закрывает файл
read (fd, buffer, count) Считывает байты в количестве

 count

 в

 buffer

write(fd, buffer, count) Записывает в файл

 count

 байтов из

 buffer

lseek(fd, offset, w) Перемещает указатель файла на

 offset

 и

 w

stat(name, buffer) Возвращает информацию о файле
chmod(name, mode) Изменяет тип защиты файла
fcntl(fd, cmd, j) Производит различные операции управления (например, блокирует

файл или его часть)

В листинге 6.3 показано, как происходит процесс ввода-вывода. Эта программа

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

 data

 и создает новый файл

 newf.

 Каж-

дый вызов возвращает дескриптор файла

 infd

 и

 outfd

 соответственно. Следующий

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

 open

 или

 creat,

 то возвращается отрицательный дескриптор

файла, который сообщает, что вызов не удался.

Листинг 6.3.

 Фрагмент программы для копирования файла с использованием

системных вызовов UNIX. Этот фрагмент написан на языке С,

поскольку в языке Java не показываются системные вызовы

низкого уровня, а нам нужно их показать

/* Открытие дескрипторов файла. */

infd = openC'data", 0);

outfd = creat("newf", ProtectionBits);

/* Цикл копирования. */

do{

count = readCinfd. buffer, bytes);

if (count > 0) write(outfd, buffer, count):

} while (count > 0):

/* Закрытие файлов.*/

close(infd):

ciose(outfd);


background image

Примеры операционных систем 495

Вызов

 read

 имеет три параметра: дескриптор файла, буфер и число байтов. Дан-

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

 count. Count

 может быть меньше, чем

 bytes,

если файл был слишком коротким. Вызов

 write

 копирует считанные байты в вы-

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

Дескрипторы файлов в системе UNIX представляют собой небольшие целые

числа (обычно до 20). Дескрипторы файлов 0, 1 и 2 соответствуют

 стандартному

вводу,

 стандартному выводу

 и

 стандартной ошибке

 соответственно. Обычно пер-

вый из них обращается к клавиатуре, а второй и третий — к дисплею, но пользо-
ватель может перенаправить их к файлам. Многие программы UNIX получают
входные данные из стандартного устройства ввода и записывают выходные дан-
ные в стандартное устройство вывода. Такие программы называются фильтрами.

С системой файлов тесно связана система директорий. Каждый пользователь

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

 корневым каталогом,

 который содержит поддиректории

 bin

(для часто используемых программ),

 dev

 (для специальных файлов устройств вво-

да-вывода),

 lib

 (для библиотек) и

 usr

 (для пользовательских директорий, как пока-

зано на рис. 6.27). В нашем примере директория

 usr

 содержит поддиректории

 ast

 и

jim.

 Директория

 ast

 включает в себя два файла

 (data

 и/оо.с) и поддиректорию

 bin,

в которую входят 4 игры.

Чтобы назвать файл, нужно указать его путь из корневого каталога. Путь со-

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

 game2

 будет таким: /usr/

ast/bin/game2. Путь, который начинается с корневого каталога, называется

 абсо-

лютным путем.

В каждый момент времени каждая работающая программа имеет текущий

 ка-

талог.

 Путь может быть связан с текущим каталогом. В этом случае в начале пути

слэш не ставится (чтобы отличить такой путь от абсолютного пути). Такой путь
называется

 относительным

 путем. Если /usr/ast — текущий каталог, то можно

получить доступ к файлу game3, используя путь bin/game3. Пользователь может
создать связь с чужим файлом, используя для этого системный вызов

 link.

 В на-

шем примере пути /usr/ast/bin/game3 и /usr/jim/jotto приводят к одному и тому
же файлу. Не разрешается применять связи к директориям, чтобы предотвратить
циклы в системе директорий. Вызовы

 open

 и

 creat

 используют и абсолютные, и

относительные пути.

Основные вызовы для оперирования с директориями в системе UNIX приведе-

ны в табл. 6.10.

 Mkdir

 создает новую директорию, a

 rmdir

 удаляет существующую

пустую директорию. Следующие три вызова применяются для чтения элементов
директорий. Первый открывает директорию, второй считывает элементы из нее,
а третий закрывает директорию.

 Chdir

 изменяет текущую директорию.

Link

 создает элемент директории, который указывает на уже существующий

файл. Например, элемент /usr/jim/jotto можно создать с помощью вызова

Iink("/usr/ast/bin/game3", "/usr/jim/jotto")

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

 Unlink

 удаляет элемент директории. Если файл


background image

496 Глава 6. Урсень операционной системы

имеет только одну связь, он удаляется. Если он имеет две и более связей, то он не
удаляется. Не имеет никакого значения, была ли удаленная связь изначально со-
зданной, или это копия. Вызов

unlink("/usr/ast/bin/game3")

делает файл

 game3

 доступным только через путь /usr/jim/jotto. Вызовы

 link

 и

 unlink

могут использоваться для перемещения файлов из одной директории в другую.

Корневой

каталог

Файлы данных

Рис. 6.27. Часть системы директорий в операционной системе UNIX


background image

Примеры операционных систем

 497

С каждым файлом (а также с каждой директорией, поскольку директория —

это тоже файл) связано битовое отображение, которое сообщает, кому разрешен
доступ к этому файлу. Отображение содержит три поля RWX (Read, Write, eXecute —
чтение, запись, выполнение). Первое из них контролирует разрешение на чтение,
запись и выполнение файлов для их владельца, второе — для других пользователей
из группы владельца, а третье — для любых пользователей. Поля RWX R-X —X
означают, что владелец файла может читать этот файл, записывать что-либо в него
и выполнять его (очевидно, файл является выполняемой программой, иначе не было

бы разрешения на его выполнение), другие члены группы могут читать и выпол-
нять его, а посторонние люди — только выполнять. Таким образом, посторонние
люди могут использовать эту программу, но не могут ее украсть (скопировать),
поскольку им запрещено чтение. Отнесение пользователей к тем или иным группам
осуществляется системным администратором, которого обычно называют

 привиле-

гированным пользователем.

 Привилегированный пользователь имеет право действо-

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

Таблица 6.10.

 Основные вызовы для работы с директориями в системе UNIX

Системный вызов Значение

mkdir(name, mode) Создает новую директорию
rmdir(name) Удаляет пустую директорию
Opendir(name) Открывает директорию для чтения
readdir(dirpointer) Читает следующий элемент директории
Closedir(dirpointer) Закрывает директорию
chdir(dirname) Изменяет текущий каталог на

 dirname

Iink(name1, name2) Создает элемент директории

 пате2,

 указывающий на

 пате 1

unlink(name) Удаляет

 пате

 из директории

Теперь рассмотрим, как файлы и директории реализованы в системе UNIX.

Более детальное описание см. в [152]. С каждым файлом (и с каждой директорией,
поскольку директория — это тоже файл) связан блок информации в 64 байта, ко-
торый называется

 индексным дескриптором (i-node).

 I-node сообщает, кто владе-

ет файлом, что разрешено делать с файлом, где найти данные и т. п. Индексные
дескрипторы для файлов расположены или последовательно в начале диска, или,
если диск разделен на группы цилиндров, — в начале цилиндра. Индексные де-
скрипторы снабжены последовательными номерами. Таким образом, система UNIX
может обнаружить i-node просто путем вычисления его адреса на диске.

Элемент директории состоит из двух частей: имени файла и номера индексного

дескриптора. Когда программа выполняет команду

openC'foo.c", 0),

система ищет текущий каталог для файла «foo.c», чтобы найти номер индексного
дескриптора для этого файла. Обнаружив номер индексного дескриптора, програм-
ма может считать его и узнать всю информацию об этом файле.

При большей длине пути файла основные шаги, изложенные выше, повторя-

ются несколько раз, пока не будет пройден весь путь. Например, чтобы найти но-
мер индексного дескриптора для пути /usr/ast/data, система сначала ищет корне-