Получить доступ

Что такое файловый дескриптор?

JuniorОперационные системы
Ещё спрашивают так:
  • Что означает ошибка Too many open files?
  • Почему в Unix «всё есть файл»?
  • Что такое stdin, stdout и stderr?
Коротко

Файловый дескриптор — небольшое целое число, по которому процесс обращается к открытому ресурсу: файлу, сокету, каналу, устройству.

  • 0, 1, 2 — stdin, stdout, stderr
  • Лимит на процесс (ulimit -n, часто 1024) — при утечке «Too many open files»
  • Сокеты тоже дескрипторы: каждое соединение тратит один

А ещё Закрывать ресурсы: try-with-resources, with, defer

Так подсказку видит пользователь sotto на живом собеседовании — за пару секунд, пока вы думаете вслух.

Подробно

Когда процесс открывает файл (open), ядро создаёт запись об открытом ресурсе и возвращает процессу индекс в его таблице — файловый дескриптор. Дальше все операции идут по номеру: read(fd, ...), write(fd, ...), close(fd).

«Всё есть файл». Через тот же интерфейс в Unix работают сокеты, каналы (| в shell), терминалы, устройства, таймеры (timerfd), события (eventfd). Поэтому одним epoll можно ждать готовности и сетевых соединений, и каналов, а перенаправление > в shell просто подменяет дескриптор 1.

Стандартные: 0 — stdin, 1 — stdout, 2 — stderr. 2>&1 — направить stderr туда же, куда stdout.

Лимиты. На процесс есть ограничение числа открытых дескрипторов — ulimit -n, по умолчанию часто 1024 (мягкий лимит). Для сервера с десятками тысяч соединений его поднимают (LimitNOFILE в systemd, nofile в limits.conf). Есть и общесистемный fs.file-max.

Too many open files (EMFILE) — обычно не «мало лимита», а утечка: файлы, сокеты или HTTP-соединения открываются и не закрываются. Ищут через ls /proc/<pid>/fd | wc -l и lsof -p <pid> — видно, чего накопилось. Лечение — закрывать ресурсы гарантированно: try-with-resources в Java, with в Python, defer в Go; переиспользовать HTTP-клиент с пулом вместо нового клиента на каждый запрос.

Наследование. После fork дочерний процесс получает копии дескрипторов; чтобы не утекали в запускаемые программы, их открывают с флагом O_CLOEXEC. Удалённый, но открытый файл продолжает занимать место на диске, пока дескриптор не закрыт — классическая загадка «диск полон, а файлов нет» с лог-файлом, который удалили у работающего процесса.

Пример

$ ulimit -n
1024
$ ls /proc/$(pgrep -f app.jar)/fd | wc -l
1019
$ lsof -p $(pgrep -f app.jar) | awk '{print $5}' | sort | uniq -c
    12 REG
   987 IPv4      # сокеты не закрываются — утечка соединений

Что хотят услышать

  • Дескриптор — номер открытого ресурса в таблице процесса.
  • Сокеты и каналы — тоже дескрипторы.
  • 0, 1, 2 и перенаправление.
  • Too many open files: лимит, утечки, диагностика через /proc и lsof.

Частые ошибки

  • Просто поднимать лимит, не поискав утечку.
  • Думать, что удалённый файл сразу освобождает место.

Что спросят дальше

Связанные вопросы

Закрытая бета

Подсказки на собеседовании — в реальном времени

sotto слышит вопрос интервьюера и показывает короткий ответ и план, как в блоке «Коротко». Оставьте контакт — пришлём доступ и промокод.

  • Промокод на 2 часа — сверх пробных 30 минут
  • Программа для Windows — скачать сразу, войти — через Яндекс ID или VK ID
  • Прямая связь с разработчиком: что улучшить — сделаем