Файловый дескриптор (File Descriptor, FD) — это неотрицательное целое число, которое ядро Linux использует для идентификации открытых файловых объектов в процессе. Это абстракция для работы с:
Технически — это индекс в таблице файловых дескрипторов процесса.
Каждый FD содержит метаданные о подключенном ресурсе:
Компонент | Описание |
---|---|
Указатель на файл | Ссылка на объект в ядре (struct file) |
Флаги доступа | Режим открытия: O_RDONLY, O_WRONLY, O_RDWR |
Позиция в файле | Текущее смещение (offset) для операций чтения/записи |
Inode объекта | Информация о файле в файловой системе |
Операции файла | Указатели на функции (read, write, poll и др.) |
Тип объекта:
ls -l /proc/<PID>/fd/
# Вывод:
lrwx------ 1 user user 64 Jan 1 10:00 0 -> /dev/pts/0
Возможные типы:
regular file
— обычный файлdirectory
— каталогsocket
— сетевой сокетpipe
— канал IPCПрава доступа:
Флаги статуса:
Блокировки:
Для процесса с PID=12345:
ls -l /proc/12345/fd # Список всех FD
cat /proc/12345/fdinfo/3 # Детали FD 3
lsof -p <PID> # Все открытые файлы процесса
ss -pln # Сокеты с PID владельца
Пример на Python:
import os
print(os.fstat(0)) # Информация о stdin (FD 0)
ulimit -n # Максимальное число открытых FD
cat /proc/sys/fs/file-max # Системный лимит
ulimit -n 65536 # Для текущей сессии
# Постоянное изменение:
echo "* soft nofile 65535" >> /etc/security/limits.conf
int fd = open("file.txt", O_RDWR | O_CREAT, 0644);
if (fd == -1) {
perror("open failed");
}
int new_fd = dup(old_fd); # Создает копию
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
Контейнеры:
docker run --ulimit nofile=1024:1024 ...
Мониторинг:
process_open_fds{job="node"}
Отладка:
watch -n 1 'ls /proc/<PID>/fd | wc -l'
Резюмируем:
Профессиональный совет: Всегда закрывайте дескрипторы явно и обрабатывайте ошибки операций ввода-вывода!