
- •Введение
- •Глава 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
Завершение процесса и системные вызовы exit
Процесс заканчивает работу в четырех случаях:
при обращении к системному вызову exit. Возврат значения из функции main эквивалентен вызову exit с тем же самым значением. Выход из функции main без возвращаемого значения равносилен возврату значения 0;
при обращении к _exit или _Exit - двум разновидностям системного вызова exit;
при получении сигнала на завершение;
в случае краха системы, причиной которого может стать все что угодно, начиная от перебоев в сети электропитания и заканчивая ошибкой в приложении или в операционной системе.
Между тремя разновидностями системного вызова exit существуют следующие различия:
_exit и _Exit ведут себя совершенно идентично, хотя _exit относится к Unix, а _Exit - к стандарту языка С;
exit - также определен стандартами языка С. Он делает то же самое, что и _exit, но кроме этого выполняет дополнительные операции по завершению процесса - вызывает функции, зарегистрированные обращением к atexit и выталкивает стандартные буферы ввода-вывода, как если бы были вызваны fflush или fclose.
Приведем краткое описание семейства функций exit:
_exit - завершает процесс без обращения к коду сборки мусора
#include <unistd.h>
void _exit(
int status /* код завершения */
);
/* В программу управления уже не возвращается */
_Exit - завершает процесс без обращения к коду сборки мусора
#include <stdlib.h>
void _Exit(
int status /* код завершения */
);
/* В программу управления уже не возвращается */
exit - завершает процесс с обращением к коду сборки мусора
#include < stdlib.h>
void exit(
int status /* код завершения */
);
/* В программу управления уже не возвращается */
Данные системные вызовы завершают работу процесса, обратившегося к нему, с кодом завершения, равным младшему байту аргумента status. Следующие побочные эффекты имеют место при любом варианте завершения процесса:
все открытые дескрипторы закрываются;
если процесс был управляющим процессом, то сеанс теряет свой управляющий терминал. Каждому процессу в сеансе передается сигнал SIGHUP, который приводит к завершению процессов;
родительский процесс извещается о завершении процесса-потомка через один из системных вызовов семейства wait;
это не оказывает непосредственного влияния на дочерние процессы, за исключением того, что их новым предком становится специальный процесс в системе, чей идентификатор потомок может получить, обратившись к системному вызову getppid.
Родительский процесс получает код завершения дочернего процесса через один из системных вызовов wait. Код завершения – это число в диапазоне от 0 до 255. Значение 0 соответствует коду успешного завершения, а ненулевое значение – какой-либо ошибке, код которой определяется самим завершившим работу приложением.
После того как процесс завершится, он прекращает свое исполнение, но остается в системе до тех пор, пока код завершения не будет передан процессу-предку. Если потомок не смог сообщить предку о своем завершении, он переходит в состояние зомби.