Работа с системными вызовами
Цель лабораторной
Понять, как прикладной код взаимодействует с операционной системой через системные вызовы, и научиться:
- корректно работать с файлами и дескрипторами;
- обрабатывать ошибки ОС;
- видеть разницу между POSIX и WinAPI;
- диагностировать проблемы через трассировку.
Теория в двух абзацах
Системный вызов — переход из пользовательского режима в режим ядра для выполнения привилегированной операции: чтение файла, создание процесса, сетевой ввод-вывод.
Важный принцип: интерфейс может выглядеть одинаково (read, open, CreateFile), но поведение зависит от ОС, файловой системы, прав доступа и текущих лимитов процесса.
Что подготовить
- Linux/macOS или WSL для POSIX-части.
- Windows (PowerShell/CMD) для WinAPI-наблюдений.
- Компилятор C/C++ (или язык с FFI/системными обертками).
- Инструменты трассировки:
strace(Linux),- Process Monitor (Windows).
Практикум: пошагово
Шаг 1. Файловый ввод-вывод через системный уровень
Сделайте программу, которая:
- Открывает файл.
- Записывает данные.
- Закрывает дескриптор.
- Повторно открывает файл и читает данные.
Проверьте:
- что все вызовы возвращают успешный код;
- что при ошибке вы получаете код причины (
errno/GetLastError).
Шаг 2. Смоделируйте ошибочные сценарии
Повторите операции с предсказуемыми ошибками:
- несуществующий путь;
- отсутствие прав;
- попытка читать из закрытого дескриптора.
Для каждого сценария зафиксируйте:
- код ошибки;
- человекочитаемое описание;
- как приложение должно реагировать (retry, fallback, прекращение).
Шаг 3. Эксперимент с дескрипторами
Запустите цикл открытия файлов без закрытия (в учебных рамках, с ограничением). Наблюдайте:
- рост числа открытых дескрипторов;
- момент достижения лимита;
- ошибку при превышении лимита.
Сделайте вывод, почему утечки дескрипторов в серверных приложениях критичны.
Шаг 4. Процессы и дочерние задачи
Реализуйте запуск дочернего процесса:
- POSIX:
fork+exec; - Windows:
CreateProcess.
Отследите:
- передачу аргументов;
- код завершения;
- поведение при зависшем дочернем процессе (таймаут/kill).
Шаг 5. Трассировка реального запуска
Запустите программу под strace или ProcMon и ответьте:
- какие системные вызовы вызываются чаще всего;
- где наблюдаются задержки;
- есть ли лишние повторные открытия/чтения.
Что включить в отчет
- Таблицу "операция -> системный вызов -> результат".
- Таблицу ошибок и способов обработки.
- Скриншоты/логи трассировки.
- Краткий разбор различий POSIX и WinAPI по вашему сценарию.
Типичные ошибки новичков
- Игнорировать коды возврата системных вызовов.
- Не закрывать дескрипторы в ветках ошибок.
- Смешивать буферизованный и небезопасный низкоуровневый I/O без понимания последствий.
- Делать platform-specific код без слоя абстракции.
Практический вывод
После этой лабораторной системные вызовы перестают быть "черным ящиком": вы начинаете видеть реальную цену операций с файлами и процессами, а также умеете диагностировать проблемы там, где уровень фреймворка уже не помогает.