← Назад к вопросам

Какие знаешь системные вызовы в Linux?

3.0 Senior🔥 151 комментариев
#Linux и администрирование

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Основные категории системных вызовов Linux

Системные вызовы (system calls) — это программный интерфейс между пользовательским пространством (user space) и ядром Linux. Они позволяют приложениям запрашивать услуги ядра, такие как управление процессами, файловыми операциями, сетевой коммуникацией и управлением памятью. Я, как DevOps-инженер, часто сталкиваюсь с ними при анализе производительности, отладке (через strace) и оптимизации систем.

Ключевые группы системных вызовов

1. Управление процессами

  • fork() / clone() — создание нового процесса (fork создает почти полную копию родителя, clone — более гибкий, используется для создания потоков).
  • exec() — семейство вызовов (execl, execvp и др.) для замены образа процесса новой программой.
  • exit() / _exit() — завершение процесса с освобождением ресурсов.
  • wait() / waitpid() — ожидание завершения дочернего процесса и получение его статуса.
  • getpid() / getppid() — получение идентификатора текущего (PID) и родительского (PPID) процессов.

2. Операции с файлами и файловыми дескрипторами

  • open() / openat() — открытие (или создание) файла, возвращает файловый дескриптор.
  • read() / write() — чтение и запись данных через файловый дескриптор.
  • close() — закрытие дескриптора.
  • lseek() — изменение позиции указателя в файле.
  • stat() / fstat() / lstat() — получение метаданных файла (inode, права, размер).
  • dup() / dup2() — дублирование файловых дескрипторов (крайне важно для перенаправления ввода-вывода в shell).
  • fcntl() — управление дескрипторами (блокировки, флаги).
// Пример: открытие файла и чтение
int fd = open("/var/log/app.log", O_RDONLY);
char buffer[1024];
ssize_t bytes_read = read(fd, buffer, sizeof(buffer));
close(fd);

3. Управление памятью

  • brk() / sbrk() — изменение размера сегмента данных процесса (устаревший, но исторически важный).
  • mmap() / munmap() — отображение файлов или анонимной памяти в адресное пространство процесса. Широко используется загрузчиками и в аллокаторах памяти (например, glibc malloc).
  • mprotect() — изменение защиты областей памяти (R/W/X).
  • madvise() — дает ядру рекомендации по использованию памяти (например, MADV_SEQUENTIAL для последовательного доступа).

4. Коммуникация между процессами (IPC)

  • pipe() — создание неименованного канала.
  • shmget() / shmat() — работа с разделяемой памятью (System V IPC).
  • msgget() / msgsnd() — очереди сообщений.
  • semget() / semop() — семафоры.
  • Более современные: eventfd(), signalfd(), timerfd_create().

5. Сетевое взаимодействие (сокеты Беркли)

  • socket() — создание конечной точки для сетевого обмена.
  • bind() — привязка сокета к адресу и порту.
  • listen() — перевод сокета в режим ожидания входящих соединений (для сервера).
  • connect() — установка соединения с удаленным сокетом (клиент).
  • accept() — принятие входящего соединения.
  • send() / recv(), sendto() / recvfrom() — отправка и прием данных.
# Практический пример использования strace для просмотра системных вызовов процесса
strace -e trace=file,network -p $(pgrep nginx)  # Мониторим файловые и сетевые вызовы Nginx

6. Управление сигналами

  • kill() — отправка сигнала процессу или группе процессов.
  • sigaction() — установка обработчика сигнала (более надежная альтернатива signal()).
  • sigprocmask() — блокировка и разблокировка сигналов.

7. Синхронизация и планирование

  • nanosleep() — приостановка выполнения процесса на заданное время.
  • gettimeofday() / clock_gettime() — получение текущего времени.
  • sched_yield() — явная передача процессора другому потоку.
  • clone() (с флагами) — часто используется для создания потоков (вместе с pthread библиотекой).

Практическая значимость для DevOps

Понимание системных вызовов критически важно для:

  • Диагностики производительности: Инструменты вроде strace, perf trace, bpftrace позволяют отслеживать вызовы и находить "узкие места" (например, множество вызовов stat() из-за неправильной конфигурации приложения).
  • Контейнеризации: Механизмы изоляции в Docker/containerd (namespaces, cgroups) тесно связаны с вызовами вроде unshare(), setns(), clone() с флагами пространств имен (CLONE_NEWPID, CLONE_NEWNET и др.).
  • Безопасности: Системы контроля доступа (например, SELinux, AppArmor) работают на уровне перехвата и проверки системных вызовов.
  • Написания скриптов и автоматизации: Понимание того, как shell команды (вроде >, |, &) преобразуются в dup2(), pipe(), fork().

Для получения полного списка на конкретной системе можно использовать команду man syscalls или заглянуть в заголовочные файлы ядра. Современные системы содержат 300-400 системных вызовов (например, x86-64 — около 350). Как инженер, я чаще всего работаю не с прямым их вызовом из кода, а с интерпретацией их активности через инструменты мониторинга и трассировки для обеспечения надежности и эффективности инфраструктуры.

Какие знаешь системные вызовы в Linux? | PrepBro