Linux. Системное программирование Р. Лав 978538800014 Содержание Об авторе Предисловие Глава 1. Введение и важнейшие концепции Системное программирование Системные вызовы Библиотека C Компилятор C Интерфейсы API и ABI Интерфейсы API Интерфейсы ABI Стандарты История POSIX и SUS Стандарты языка C Linux и стандарты Эта книга и стандарты Концепции программирования в Linux Файлы и файловая система Процессы Пользователи и группы Разрешения Сигналы. Взаимодействие процессов Заголовки Обработка ошибок Знакомство с системным программированием Глава 2. Файловый ввод-вывод Открытие файлов. Системный вызов open() Владельцы новых файлов Разрешения новых файлов Функция creat() Возвращаемые значения и коды ошибок Чтение файла при помощи системного вызова read() Возвращаемые значения Считывание всех байтов Считывание без блокировки. Прочие значения ошибки Лимиты размера для вызова read() Запись при помощи системного вызова write() Частичная запись Режим присоединения Запись без блокировки Прочие коды ошибок Ограничения размера для вызова write() Поведение вызова write() Синхронизированный ввод-вывод 14 15 17 18 19 20 20 21 21 22 23 23 24 25 25 26 26 34 36 37 38 39 39 39 43 44 45 45 48 48 50 51 51 52 53 54 54 55 55 56 57 57 57 58 58 60 fsync() и fdatasync() Флаг O_SYNC Флаги O_DSYNC и O_RSYNC Прямой ввод-вывод Закрытие файлов Значения ошибок Поиск при помощи lseek() Поиск за пределами конца файла Значения ошибок Ограничения Позиционное чтение и запись Значения ошибок Усечение файлов Мультиплексированный ввод-вывод select() Системный вызов poll() Сравнение poll() и select() Внутреннее устройство ядра Виртуальная файловая система Страничный кэш Страничная отложенная запись Заключение Глава 3. Буферизованный ввод-вывод Ввод-вывод с пользовательским буфером Размер блока Стандартный ввод-вывод Указатели файла Открытие файлов Режимы Открытие потока данных при помощи дескриптора файла Закрытие потоков данных Закрытие всех потоков данных Чтение из потока данных Чтение по одному символу за раз Считывание строки целиком Считывание двоичных данных Запись в поток данных Запись одного символа Запись строки символов Запись двоичных данных Пример программы с использованием буферизованного ввода-вывода Поиск в потоке данных Получение текущей позиции в потоке данных Сброс потока данных Ошибки и конец файла Получение связанного дескриптора файла Управление буферизацией Безопасность потоков выполнения Блокировка файла вручную Операции над потоками без блокировки Недостатки стандартного ввода-вывода Заключение 60 62 63 64 64 65 66 67 67 68 68 69 69 71 72 78 82 83 83 84 86 87 88 88 89 91 91 92 92 93 94 94 94 94 95 97 98 98 99 99 100 101 103 103 104 105 105 107 108 109 110 111 Глава 4. Расширенный файловый ввод-вывод Разбросанный ввод-вывод Системные вызовы readv() и writev() Интерфейс event poll Создание нового экземпляра epoll Управление epoll Ожидание событий при помощи epoll События, запускаемые фронтом, и события, запускаемые уровнем. Отображение файлов в память Системный вызов mmap() Системный вызов munmap() Пример отображения Преимущества системного вызова mmap() Недостатки системного вызова mmap() Изменение размера отображения Изменение защиты отображения Синхронизация файла с отображением Добавление советов относительно отображения Советы относительно обычного файлового ввода-вывода Системный вызов posix_fadvise() Системный вызов readahead() Советы стоят недорого Синхронизированные, синхронные и асинхронные операции Асинхронный ввод-вывод Планировщики ввода-вывода и производительность ввода-вывода Адресация диска Жизнь планировщика ввода-вывода Помощь при считывании Выбор и настройка планировщика ввода-вывода Оптимизация производительности ввода-вывода Заключение Глава 5. Управление процессами Идентификатор процесса Выделение идентификатора процесса Иерархия процессов Тип pid_t Получение идентификатора процесса и идентификатора родительского процесса Запуск процесса Семейство вызовов exec Системный вызов fork() Завершение процесса Прочие способы завершения Библиотечный вызов atexit() Функция on_exit() SIGCHLD Ожидание завершенных дочерних процессов Ожидание определенного процесса Еще больше гибкости при ожидании процессов BSD говорит свое слово: wait3() и wait4() Запуск и ожидание нового процесса Зомби Пользователи и группы 112 113 113 118 118 119 122 123 124 124 129 130 131 132 133 134 135 136 139 139 141 142 142 144 145 146 147 148 151 152 158 159 159 160 161 161 161 162 162 166 170 171 172 173 173 174 176 179 181 182 184 185 Реальные, действительные и сохраненные идентификаторы пользователя и группы Изменение реального и сохраненного идентификатора пользователя или группы Изменение действительного идентификатора пользователя или группы Изменение идентификаторов пользователя и группы, стиль BSD. Изменение идентификаторов пользователя и группы, стиль HP-UX. Манипулирование предпочтительными идентификаторами пользователя/группы Поддержка сохраненных идентификаторов пользователя Получение идентификаторов пользователя и группы. Сеансы и группы процессов Системные вызовы сеансов. Системные вызовы для группы процессов Устаревшие функции для группы процессов Демоны Заключение Глава 6. Расширенное управление процессами Планирование процессов Запись с O большим Кванты времени Процессы, ограниченные вводом-выводом, и процессы, ограниченные процессором Вытесняющее планирование Управление потоками Уступка процессора Правомерное использование Уступка, прошлое и настоящее Приоритеты процессов Системный вызов nice() Системные вызовы getpriority() и setpriority() Приоритеты ввода-вывода Привязка процессов к процессорам Системные вызовы sched_getaffinity() и sched_setaffinity() Системы реального времени Жесткие и мягкие системы реального времени Задержка, дрожание и предельные сроки Поддержка процессов реального времени в Linux Политики планирования и приоритеты в Linux Установка параметров планирования Интерфейс sched_rr_get_interval() Предосторожности при использовании процессов реального времени Детерминизм Лимиты ресурсов Лимиты Установка и проверка лимитов Глава 7. Управление файлами и каталогами Файлы и их метаданные Семейство stat Разрешения Владение Расширенные атрибуты Каталоги Текущий рабочий каталог Создание каталогов Удаление каталогов 186 187 188 189 189 190 190 191 191 193 195 196 197 199 200 200 202 202 203 204 205 205 206 207 208 209 210 211 212 213 216 216 217 218 219 223 227 228 229 232 233 237 239 239 239 243 244 247 256 257 263 264 Чтение содержимого каталога Ссылки Жесткие ссылки Символические ссылки Удаление ссылки. Копирование и перемещение файлов Копирование Перемещение Узлы устройств Специальные узлы устройств Генератор случайных чисел Внеполосная коммуникация Мониторинг событий файлов Инициализация inotify Стражи События inotify Расширенные параметры стражей Удаление стража inotify Проверка размера очереди событий Разрушение экземпляра inotify Глава 8. Управление памятью Адресное пространство процесса Страницы и подкачка страниц Области памяти Выделение динамической памяти Выделение массивов Изменение размера выделенной памяти Освобождение динамической памяти Выравнивание Управление сегментом данных Анонимные отображения в памяти Создание анонимных отображений в памяти Отображение /dev/zero Расширенное выделение памяти Тонкая настройка при помощи malloc_usable_size() и malloc_trim() Отладка выделения памяти Получение статистики Выделение памяти на основе стека Дублирование строк в стеке Массивы переменной длины Выбор механизма выделения памяти Манипулирование памятью Установка байтов Сравнение байтов Перемещение байтов Поиск байтов Прочее манипулирование байтами Блокировка памяти Блокировка части адресного пространства Блокировка всего адресного пространства Разблокировка памяти Лимиты блокирования 266 269 270 271 273 275 275 275 278 278 279 280 281 282 283 285 288 289 289 290 291 291 292 293 294 296 297 299 301 305 306 307 309 310 313 314 314 315 317 317 319 320 320 321 322 323 324 324 325 326 327 328 Находится ли страница в физической памяти? Уступающее выделение памяти Принятие чрезмерных обязательств и OOM Глава 9. Сигналы Концепции сигналов Идентификаторы сигналов Сигналы, поддерживаемые в Linux Простейшее управление сигналами Ожидание сигнала, любого сигнала Примеры Запуск и наследование Сопоставление номеров сигналов и строк Отправка сигнала Разрешения Примеры Отправка сигнала себе Отправка сигнала всей группе процессов Повторный вход Функции, гарантированно поддерживающие повторный вход Наборы сигналов Больше функций для наборов сигналов Блокирование сигналов Извлечение ожидающих сигналов Ожидание набора сигналов Расширенное управление сигналами Структура siginfo_t Великолепный мир si_code Отправка сигнала с полезной нагрузкой Пример Заключение Глава 10. Время Структуры данных для работы со временем Исходное представление А теперь точность до микросекунд Еще лучше: точность до наносекунд Разбор времени Тип для времени процесса Часы POSIX Разрешение источника времени Получение текущего времени дня Лучший интерфейс Расширенный интерфейс Получение времени процесса Установка текущего времени дня Установка времени с точностью Расширенный интерфейс для установки времени Различные действия со временем Подстройка системных часов Засыпание и ожидание Засыпание с точностью до микросекунд Засыпание с точностью до наносекунд Расширенный подход к засыпанию 328 329 329 332 333 334 334 340 341 342 344 345 345 346 347 347 347 348 349 351 351 352 353 353 354 356 358 361 362 363 364 367 367 367 368 368 370 370 370 372 372 373 374 374 375 376 376 378 382 382 383 385 Переносимый способ засыпания Превышение пределов Альтернативы засыпанию Таймеры Простые сигнализации Интервальные таймеры Расширенные таймеры Приложение. Расширения GCC языка C GNU C Подставляемые функции Подавление подстановки Чистые функции Постоянные функции Функции, не возвращающие результат Функции, выделяющие память Как заставить вызывающего проверять возвращаемое значение Как пометить функцию как устаревшую Как пометить функцию как используемую Как пометить функции или параметры как неиспользующиеся Упаковка структуры Увеличение границы выравнивания переменной Помещение глобальных переменных в регистр Комментирование ветвей Получение типа выражения Получение границы выравнивания типа Смещение члена структуры Получение адреса возврата функции Диапазоны оператора case Арифметика указателей типа void и указателей на функции Более переносимо и красиво Библиография. Книги по языку программирования C Книги по программированию в Linux Книги, посвященные ядру Linux Книги по дизайну операционной системы 387 387 388 388 388 389 391 397 397 398 399 399 400 400 400 401 401 401 402 402 402 403 404 405 405 406 407 407 408 408 410 410 411 412 413