Главная страница

Системное программирование Линукс. Linux. Системное программирование. Вступление


Скачать 0.65 Mb.
НазваниеLinux. Системное программирование. Вступление
АнкорСистемное программирование Линукс
Дата23.01.2023
Размер0.65 Mb.
Формат файлаpdf
Имя файлаLinuxSystemProgramming.pdf
ТипКраткое содержание
#900372
страница1 из 14
  1   2   3   4   5   6   7   8   9   ...   14

Linux. Системное программирование.


Вступление
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Целевая аудитория и необходимые предпосылки . . . . . . . . . . . . . . . . . . . . . . 19
Краткое содержание . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Версии, рассмотренные в книге . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Условные обозначения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
Работа с примерами кода . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Глава 1.
Введение и основополагающие концепции . . . . . . . . . . . . . . . . . . . . . . 27
Системное программирование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Зачем изучать системное программирование . . . . . . . . . . . . . . . . . . . 28
Краеугольные камни системного программирования . . . . . . . . . . . . . 29
Системные вызовы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
Библиотека C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Компилятор C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
API и ABI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
ABI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Стандарты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
История POSIX и SUS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Стандарты языка C . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Linux и стандарты . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Стандарты и эта книга . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Концепции программирования в Linux . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Файлы и файловая система . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Процессы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
Пользователи и группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47
Права доступа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

Оглавление
7
Сигналы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
Межпроцессное взаимодействие . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Заголовки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Обработка ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
Добро пожаловать в системное программирование . . . . . . . . . . . . . . . . . . . . 53
Глава 2.
Файловый ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Открытие файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Системный вызов open() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Владельцы новых файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Права доступа новых файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Функция creat() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Возвращаемые значения и коды ошибок . . . . . . . . . . . . . . . . . . . . . . 61
Считывание с помощью read() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Возвращаемые значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Считывание всех байтов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
Неблокирующее считывание . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Другие значения ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Ограничения размера для read() . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Запись с помощью write() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Случаи частичной записи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Режим дозаписи . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Неблокирующая запись . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
Другие коды ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Ограничения размера при использовании write() . . . . . . . . . . . . . . . . 68
Поведение write() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Синхронизированный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
fsync() и fdatasync() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
sync() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Флаг O_SYNC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
Флаги O_DSYNC и O_RSYNC . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Непосредственный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Закрытие файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Значения ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Позиционирование с помощью Iseek() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Поиск с выходом за пределы файла . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Ограничения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Позиционное чтение и запись . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 79
Усечение файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80

8
Оглавление
Мультиплексный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
select() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Системный вызов poll() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Сравнение poll() и select() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
Внутренняя организация ядра . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Виртуальная файловая система . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
Страничный кэш . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 94
Страничная отложенная запись . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
Глава 3.
Буферизованный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
Ввод-вывод с пользовательским буфером . . . . . . . . . . . . . . . . . . . . . . . . . . .100
Стандартный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .102
Открытие файлов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .103
Открытие потока данных с помощью файлового дескриптора . . . . . . . . . . . .104
Закрытие потоков данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .105
Считывание из потока данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .106
Считывание одного символа в момент времени . . . . . . . . . . . . . . . . .106
Считывание целой строки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .107
Считывание двоичных данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .109
Запись в поток данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .110
Запись отдельного символа . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .110
Запись строки символов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111
Запись двоичных данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .111
Пример программы, в которой используется буферизованный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112
Позиционирование в потоке данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .113
Сброс потока данных . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .115
Ошибки и конец файла . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .116
Получение ассоциированного файлового дескриптора . . . . . . . . . . . . . . . . . .117
Управление буферизацией . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .117
Безопасность программных потоков . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .119
Блокировка файлов вручную . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .120
Неблокируемые потоковые операции . . . . . . . . . . . . . . . . . . . . . . . . .122
Недостатки стандартного ввода-вывода . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .123
Глава 4.
Расширенный файловый ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . .125
Фрагментированный ввод-вывод . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .125
Системные вызовы readv() и writev() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .126

Оглавление
9
Возвращаемые значения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .127
Пример использования writev() . . . . . . . . . . . . . . . . . . . . . . . . . . . . .128
Пример использования readv() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .129
Реализация . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .130
Опрос событий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .131
Создание нового экземпляра epoll . . . . . . . . . . . . . . . . . . . . . . . . . . .131
Управление epoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .132
Ожидание событий с помощью epoll . . . . . . . . . . . . . . . . . . . . . . . . . .135
Сравнение событий, запускаемых по фронту и по уровню сигнала . . .136
Отображение файлов в память . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
mmap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .137
Системный вызов munmap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .142
Пример отображения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .143
Преимущества mmap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .144
Недостатки mmap() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .145
Изменение размеров отображения . . . . . . . . . . . . . . . . . . . . . . . . . . .145
Изменение защиты отображения . . . . . . . . . . . . . . . . . . . . . . . . . . . .147
Синхронизация файла с помощью отображения . . . . . . . . . . . . . . . . .147
Извещения об отображении . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .149
Извещения об обычном файловом вводе-выводе . . . . . . . . . . . . . . . . . . . . . .151
Системный вызов posix_fadvise() . . . . . . . . . . . . . . . . . . . . . . . . . . . .151
Системный вызов readahead() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .153
Рекомендации почти ничего не стоят . . . . . . . . . . . . . . . . . . . . . . . . .153
Синхронизированные, синхронные и асинхронные операции . . . . . . . . . . . . .154
Планировщики и производительность ввода-вывода . . . . . . . . . . . . . . . . . . .156
Адресация диска . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .156
Жизненный цикл планировщика ввода-вывода . . . . . . . . . . . . . . . . . .157
Помощь при считывании . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .158
Выбор и настройка планировщика ввода-вывода . . . . . . . . . . . . . . . .162
Оптимизация производительности ввода-вывода . . . . . . . . . . . . . . . .163
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .170
Глава 5.
Управление процессами . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
Программы, процессы и потоки . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .171
Идентификатор процесса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .172
Выделение идентификатора процесса . . . . . . . . . . . . . . . . . . . . . . . .173
Иерархия процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .173
pid_t . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
Получение идентификаторов процесса и родительского процесса . . .174

10
Оглавление
Запуск нового процесса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .174
Семейство вызовов exec . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .175
Системные вызовы fork() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .179
Завершение процесса . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .182
Другие способы завершения . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .183
atexit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .184
on_exit() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
SIGCHLD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .185
Ожидание завершенных дочерних процессов . . . . . . . . . . . . . . . . . . . . . . . . .185
Ожидание определенного процесса . . . . . . . . . . . . . . . . . . . . . . . . . .188
Еще больше гибкости при ожидании . . . . . . . . . . . . . . . . . . . . . . . . .190
На сцену выходит BSD: wait3() и wait4() . . . . . . . . . . . . . . . . . . . . . . .192
Запуск и ожидание нового процесса . . . . . . . . . . . . . . . . . . . . . . . . . .193
Зомби . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .195
Пользователи и группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .196
Реальные, действительные и сохраненные идентификаторы пользователя и группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .197
Изменение реального или сохраненного идентификатора пользователя или группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .198
Изменение действительного идентификатора пользователя или группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199
Изменение идентификаторов пользователя и группы согласно стилю BSD . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .199
Изменение идентификаторов пользователя и группы согласно стилю HP-UX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .200
Действия с предпочтительными идентификаторами пользователя или группы . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .201
Поддержка сохраненных пользовательских идентификаторов . . . . . .201
Получение идентификаторов пользователя и группы . . . . . . . . . . . . .201
Сессии и группы процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .202
Системные вызовы сессий . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .204
Системные вызовы групп процессов . . . . . . . . . . . . . . . . . . . . . . . . . .205
Устаревшие функции для группы процессов . . . . . . . . . . . . . . . . . . . .206
Демоны . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .207
Резюме . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .209
Глава 6.
Расширенное управление процессами . . . . . . . . . . . . . . . . . . . . . . . . .210
Планирование процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .210
Кванты времени . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .211
Процессы ввода-вывода против ограниченных процессором . . . . . . . .212

Оглавление
11
Приоритетное планирование . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .213
Completely Fair Scheduler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .213
Высвобождение ресурсов процессора . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .215
Приоритеты процессов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .216
nice() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .217
getpriority() и setpriority() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .218
Приоритеты ввода-вывода . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .219
Привязка процессов к процессору . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .220
Системы реального времени . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .223
Мягкие и жесткие системы реального времени . . . . . . . . . . . . . . . . . .224
Задержка, колебание и временное ограничение . . . . . . . . . . . . . . . . .225
Поддержка реального времени в Linux . . . . . . . . . . . . . . . . . . . . . . . .226
Политики планирования и приоритеты в Linux . . . . . . . . . . . . . . . . . .226
Установка параметров планирования . . . . . . . . . . . . . . . . . . . . . . . . .230
sched_rr_get_interval() . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .233
Предосторожности при работе с процессами реального времени . . . .235
Детерминизм . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .235
Лимиты ресурсов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .238
Лимиты по умолчанию . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .242
Установка и проверка лимитов . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .243
Коды ошибок . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .244
  1   2   3   4   5   6   7   8   9   ...   14


написать администратору сайта