
- •И.Н.Акуленок, а.В.Акуленок
- •Часть I. Основы операционной системы unix Утверждено советом университета
- •Введение
- •Глава 1. История создания ос unix
- •Реализации oc unix
- •Unix на платформе Intel
- •Доля компьютеров с ос unix (1993 год)
- •Продажи unix–серверов (III квартал 2007 года)
- •1.1. Первые шаги по созданию unix
- •1.2. Исследовательские версии unix
- •1.3. Основные стандарты
- •1.3.1. Основные задачи стандартизации
- •1.4. Разработчики операционных систем
- •1.4.1. Версии at&t
- •1.4.2. Версии Microsoft/sco
- •1.4.3. Версии университета Беркли
- •1.4.4. Версии компании Sun
- •1.4.5. Версии компании Nowell
- •1.4.6. Популярные версии unix
- •1.4.7. Свободно распространяемые системы unix
- •1.5. Реализация ядра unix
- •1.5.1. Микроядро Mach
- •1.5.2. Микроядро Chorus
- •1.6 Характеристики oc unix
- •1.6.1.Файловая система
- •1.6.2. Многозадачность
- •1.6.3. Многопользовательский режим
- •1.6.4. Мобильность
- •1.6.5. Виртуальная память
- •1.6.6. Связь между задачами
- •1.6.7. Внешние устройства
- •1.6.8. Связь между компьютерами
- •1.6.9. Графический пользовательский интерфейс
- •1.6.10. Безопасность
- •1.6.11. Поддержка баз данных
- •1.6.12. Наличие стандартов
- •1.6.13. Открытость
- •1.6.14. Разработка программного обеспечения
- •1.7. Контрольные вопросы
- •1.8. Тесты
- •Глава 2. Функционирование ос unix
- •2.1. Ядро
- •2.1.1. Функции ядра
- •2.1.2. Структура ядра
- •2.1.3. Файловая подсистема
- •2.1.4. Подсистема управления процессами
- •2.1.5. Подсистема ввода/вывода
- •2.2. Командный процессор Shell
- •2.3. Программы–утилиты
- •2.4. Контрольные вопросы
- •2.5. Тесты
- •Глава 3. Процессы
- •3.1. Контекст процесса
- •3.3. Типы процессов
- •3.3.1. Системные процессы
- •3.3.2. Демоны
- •3.3.3. Прикладные процессы
- •3.4. Атрибуты процесса
- •3.4.1. Идентификатор процесса
- •3.4.2. Идентификатор родительского процесса
- •3.4.3. Приоритет процесса
- •3.4.4. Терминальная линия
- •3.4.5. Реальный и эффективный идентификаторы пользователя
- •3.4.6. Реальный и эффективный идентификаторы группы
- •3.4.7. Идентификатор терминальной группы
- •3.5. Иерархия процессов
- •3.6. Взаимодействие процессов
- •3.6.1. «Отцы», «дети», «сироты», «зомби»
- •3.7. Системные вызовы
- •3.7.1. Механизм создания процесса и запуска программы
- •3.7.2. Графический пример дерева процессов
- •3.8. Связи между процессами
- •3.8.1. Сигналы
- •Сигналы posix 1.1
- •3.8.2. Очереди сообщений
- •3.8.3. Семафоры
- •3.8.4. Совместная память
- •3.8.5. Программные каналы
- •3.8.6. Программные гнезда
- •3.9. Контрольные вопросы
- •3.10. Тесты
- •Глава 4. Файловая система unix
- •4.1. Имена файлов
- •4.2. Структура файловой системы
- •4.2.1. Загрузочный блок
- •4.2.2. Суперблок
- •4.2.3 Дескрипторы файлов
- •4.2.4. Блоки данных и свободные блоки
- •4.3. Типы файлов
- •4.3.1. Обычные файлы
- •4.3.2. Каталоги
- •4.3.4. Символические связи
- •4.3.5. Fifo – Именованные каналы
- •4.3.6. Сокеты
- •4.3.7. Обозначение типов файлов
- •Типы файлов
- •4.4. Дескриптор обычного файла
- •4.5. Дескриптор каталога
- •4.6. Дескриптор специального файла
- •4.7. Системная таблица файлов
- •4.8. Монтирование файловых систем
- •4.9. Демонтирование файловых систем
- •4.10. Проверка и восстановление файловых систем
- •4.11. Журналирование файловых систем
- •4.12. Контрольные вопросы
- •4.13. Тесты
- •Глава 5. Этапы начальной загрузки ос Unix
- •5.1. Загрузка и инициализация ядра
- •5.2. Распознавание и конфигурирование устройств
- •5.3. Создание спонтанных процессов
- •5.4. Выполнение команд оператора
- •5.5. Выполнение командных файлов запуска системы
- •5.6. Переход в многопользовательский режим
- •5.7. Контрольные вопросы
- •5.8. Тесты
- •Глава 6. Обзор командных файлов
- •6.1. Процесс init
- •6.1.1. Формат файла inittab
- •6.1.2. Уровни выполнения
- •Уровни выполнения
- •6.1.3. Дисциплины обработки процесса
- •Дисциплины обработки процесса
- •6.1.4. Запуск и этапы работы процесса init
- •6.2. Процесс rc
- •6.2.1. Сценарии запуска системы Solaris
- •6.3. Процесс cron
- •6.4. Процесс регистрации пользователей
- •6.5. Контрольные вопросы
- •6.6. Тесты
- •Глава 7. Останов системы
- •7.1. Выключение питания
- •7.2. Команда shutdown
- •7.3. Команда halt
- •7.4. Изменение уровня выполнения процесса init
- •Глава 8. Задачи системного администрирования
- •8.1. Инструменты администрирования
- •8.1.1. Администрирование aix
- •8.1.2. Администрирование hp-ux
- •8.1.3. Администрирование Solaris
- •8.1.4. Администрирование Linux
- •8.2. Пользователь root
- •8.2.1. Команда su
- •8.3. Добавление новых пользователей в систему
- •8.3.1. Файл /etc/passwd
- •Идентификаторы пользователей
- •8.3.2. Файл /etc/group
- •8.4. Контрольные вопросы
- •8.5. Тесты
- •Литература
- •Содержание
- •Глава 1. История создания ос unix 6
- •Глава 2. Функционирование ос unix 51
- •Глава 3. Процессы 75
- •Глава 4. Файловая система unix 116
- •Акуленок Ирина Николаевна Акуленок Анатолий Васильевич
- •Часть I. Основы операционной системы unix
3.7. Системные вызовы
В любой операционной системе поддерживается механизм, который позволяет пользовательским программам обращаться к услугам ядра операционной системы. В ОС UNIX такие средства называют системными вызовами. Они служат для создания и координации процессов и являются базовыми обслуживающими программами.
Системные вызовы (systems calls) – это интерфейс между операционной системой и пользовательской программой. Они создают, удаляют и используют различные объекты, главные из которых – процессы и файлы. Пользовательская программа запрашивает сервис у операционной системы, осуществляя системный вызов. Имеются библиотеки процедур, которые загружают машинные регистры определенными параметрами и осуществляют прерывание процессора, после чего управление передается обработчику данного вызова, входящему в ядро операционной системы. Цель таких библиотек – сделать системный вызов похожим на обычный вызов подпрограммы.
Основное отличие состоит в том, что при системном вызове задача переходит в привилегированный режим или режим ядра (kernel mode). Поэтому системные вызовы иногда еще называют программными прерываниями, в отличие от аппаратных прерываний, которые чаще называют просто прерываниями.
В этом режиме работает код ядра операционной системы, причем исполняется он в адресном пространстве и в контексте вызвавшей его задачи. Таким образом, ядро операционной системы имеет полный доступ к памяти пользовательской программы, и при системном вызове достаточно передать адреса одной или нескольких областей памяти с параметрами вызова и адреса одной или нескольких областей памяти для результатов вызова.
Системные вызовы для управления просты, но эффективны. В их число входят следующие:
fork() – создать процесс. Для создания нового процесса используется системный вызов fork(). В среде программирования нужно относиться к этому системному вызову как к вызову функции, возвращающей целое значение – идентификатор порожденного процесса, который затем может использоваться для управления (в ограниченном смысле) порожденным процессом. Реально, все процессы системы UNIX, кроме начального, запускаемого при раскрутке системы, образуются при помощи системного вызова fork().
Вот что делает ядро системы при выполнении системного вызова fork():
Выделяет память под описатель нового процесса в таблице описателей процессов.
Назначает уникальный идентификатор процесса (PID) для вновь образованного процесса.
Образует логическую копию процесса, выполняющего системный вызов fork(), включая полное копирование содержимого виртуальной памяти процесса–предка во вновь создаваемую виртуальную память, а также копирование составляющих ядерного статического и динамического контекстов процесса–предка.
Увеличивает счетчики открытия файлов (процесс–потомок автоматически наследует все открытые файлы своего родителя).
Возвращает вновь образованный идентификатор процесса в точку возврата из системного вызова в процессе–предке и возвращает значение 0 в точке возврата в процессе–потомке.
exec() – выполнить файл. Системная функция exec() дает возможность процессу запускать другую программу, при этом соответствующий этой программе исполняемый файл будет располагаться в пространстве памяти процесса. Содержимое пользовательского контекста после вызова функции становится недоступным, за исключением передаваемых функции параметров, которые переписываются ядром из старого адресного пространства в новое.
exit() – завершить процесс. В системе UNIX процесс завершает свое выполнение, запуская системную функцию exit(). После этого процесс переходит в состояние "прекращения существования", освобождает ресурсы и ликвидирует свой контекст. Система не накладывает никакого ограничения на продолжительность выполнения процесса, и зачастую процессы существуют в течение довольно длительного времени. Нулевой процесс (программа подкачки) и процесс 1 (init), к примеру, существуют на протяжении всего времени жизни системы. Продолжительными процессами являются также getty–процессы, контролирующие работу терминальной линии, ожидая регистрации пользователей, и процессы общего назначения, выполняемые под руководством администратора.
kill() – послать сигнал. Процессы могут сами посылать сигналы, используя системную функцию kill().
signal()– задать реакцию на сигнал;
wait() – ждать завершения процесса. Чтобы процесс–предок мог синхронизовать свое выполнение с выполнением своих процессов–потомков, существует системный вызов wait(). Выполнение этого системного вызова приводит к приостановке выполнения процесса до тех пор, пока не завершится выполнение какого–либо из процессов, являющихся его потомками. В качестве прямого параметра системного вызова wait() указывается адрес памяти (указатель), по которому должна быть возвращена информация, описывающая статус завершения очередного процесса–потомка, а ответным (возвратным) параметром является PID завершившегося процесса–потомка.