- •Введение
- •Глава 1. Фундаментальные концепции unix Систем
- •Программы, процессы и потоки
- •Сигналы
- •Идентификаторы процессов, группы процессов и сеансы
- •Система прав
- •Другие атрибуты процесса
- •Межпроцессное взаимодействие
- •Использование системных вызовов
- •Краткие описания функций и обработка ошибок
- •Контрольные вопросы
- •Литература
- •Глава 2. Базовые операции ввода-вывода
- •Файловые операции ввода - вывода
- •Стандартные дескрипторы
- •Системные вызовы open и creat
- •Системный вызов umask
- •Системный вызов unlink
- •Текущая позиция в файле
- •Системный вызов write
- •2.8. Системный вызов read
- •2.9. Системный вызов close
- •2.10. Системный вызов lseek
- •2.11. Системные вызовы pread и pwrite
- •2.12. Системные вызовы truncate и ftruncate
- •Контрольные вопросы
- •Литература
- •Глава 3. Дополнительные операции файлового ввода_вывода
- •Низкоуровневый доступ к файловой системе
- •Жесткие и символические ссылки
- •Системный вызов getcwd
- •Отображение метаданных файла
- •Системные вызовы getpwuid, getgrgid и getlogin
- •Каталоги
- •Системные вызовы chdir и fchdir
- •Системные вызовы mkdir и rmdir
- •Контрольные вопросы
- •Литература
- •Глава 4. Процессы и потоки
- •4.1. Среда окружения
- •Системный вызов exec
- •Системный вызов fork
- •Завершение процесса и системные вызовы exit
- •Системные вызовы wait, waitpid и waitid
- •Получение и изменение идентификаторов пользователя и группы
- •Получение и изменение приоритета
- •Контрольные вопросы
- •Литература
- •Глава 5. Механизмы межпроцессного взаимодействия
- •5.1. Каналы
- •5.2. Системные вызовы dup и dup2
- •5.3. Двунаправленное взаимодействие с использованием однонаправленных каналов
- •Контрольные вопросы
- •Литература
- •Глава 6.Механизмы взаимодействия процессов
- •Именованные каналы (fifo)
- •Системные вызовы для работы с очередями сообщений posix
- •Семафоры
- •Системные вызовы для работы с общей памятью posix
- •Контрольные вопросы
- •Литература
- •Глава 7.Сетевое взаимодействие и сокеты
- •Основные системные вызовы для работы с сокетами, образующими логические соединения
- •Обслуживание нескольких клиентов
- •Адресация сокетов
- •In_port_t sin_port; /* номер порта (uint16_t) */
- •In_addr_t s_addr; /* адрес iPv4 (uint32_t) */
- •Домен адресов af_inet6
- •In_port_t sin6_port; /* номер порта (uint16_t) */
- •Доменная система именования
- •Параметры сокетов
- •Контрольные вопросы
- •Литература
- •Глава 8.Сигналы и таймеры
- •Введение в сигналы
- •Жизненный цикл сигналов
- •Типы сигналов
- •Системный вызов sigaction
- •Контрольные вопросы
- •Литература
- •Заключение
- •Список литературы
- •Глава 2. Базовые операции ввода-вывода 14
- •Глава 3. Дополнительные операции файлового ввода_вывода 25
- •Глава 6. Механизмы взаимодействия процессов 58
Программы, процессы и потоки
Программа – это набор команд и данных, который хранится в обычном файле на диске. В индексном узле этот файл помечен как исполняемый, а содержимое файла организовано согласно определенным правилам. Сначала исходный текст программы, написанной на каком-то языке программирования, сохраняется в обычном файле, который называют текстовым файлом, потому что он содержит строки текста. Затем создается другой обычный файл, называемый объектным файлом – он содержит машинный код, полученный в результате преобразования исходной программы. Для выполнения этого преобразования используется компилятор. Если в объектном файле имеются все необходимые функции, он отмечается, как исполняемый и может быть выполнен. В противном случае разработчик должен с помощью компоновщика или загрузчика связать объектный файл с другими объектными файлами, которые могут быть организованы в библиотеки. Если компоновщик обнаруживает все нужные файлы, то он создает исполняемый файл.
Чтобы запустить программу, ядро сначала должно создать новый процесс – среду, в которой выполняется программа. Процесс состоит из трех сегментов: сегмента команд, сегмента пользовательских данных и сегмента системных данных. Программа используется для инициализации сегментов команд и пользовательских данных. После этой инициализации процесс начинает все сильнее отличаться от выполняемой в нем программы. Кроме того процесс может получать в свое распоряжение дополнительную память, открывать файлы и приобретать другие ресурсы, отсутствующие в программе.
Пока процесс выполняется, ядро следит за его потоками – отдельными путями выполнения команд, которые потенциально могут осуществлять чтение и запись одних и тех же данных процесса. Системные данные процесса включают такие атрибуты, как текущий каталог, дескрипторы открытых файлов, использованное время процессора и т.д. Процесс не может читать или изменять свои системные данные непосредственно, так как они находятся вне его адресного пространства. Вместо этого для чтения и изменения атрибутов используются различные системные вызовы.
Выполняемый процесс может поручить ядру, создать другой процесс и стать родителем нового дочернего процесса. Дочерний процесс наследует большинство атрибутов системных данных родителя. Например, если родительскому процессу соответствуют какие-то открытые файлы, для дочернего процесса эти файлы также будут открыты. Преемственность такого рода – фундаментальный принцип Unix. Это отличается от создания потоком нового потока. Потоки одного процесса в большинстве отношений равны и ничего не наследуют друг от друга. Все потоки могут обращаться ко всем данным и ресурсам.
Сигналы
Ядро может отправить процессу сигнал. Сигнал может быть отправлен процессу ядром, самим собой, другим процессом или пользователем.
Примером сигнала, исходящего из ядра, может служить сигнал нарушения сегментации, отправляемый процессу, когда он пытается обратиться к памяти, расположенной вне его адресного пространства. В качестве примера сигнала, отправляемого процессом самому себе, можно привести сигнал, отправляемый функцией abort для завершения процесса с созданием дампа памяти. Примером сигнала, отправляемого одним процессом другому, является сигнал завершения, отправляемый одним из нескольких связанных процессов, когда он решает завершить целое семейство процессов. Наконец, примером пользовательского сигнала может служить сигнал прерывания, отправляемый всем созданным пользователем процессам при нажатии Ctrl –c.
Существует примерно 28 типов сигналов (оно колеблется в зависимости от версии Unix). Процесс может принять действие по умолчанию, которое обычно приводит к завершению процесса, он может проигнорировать сигнал или перехватить сигнал и выполнить функцию, называемую обработчиком сигнала. Тип сигнала (например, SIGALRM) передается в обработчик как аргумент. Когда обработчик сигнала возвращает управление, выполнение процесса возобновляется с точки прерывания.