Ядро считает открытые файлы каждого процесса отдельно и каждому ставит свой потолок.
Открытый файл процесс видит как номер — дескриптор. Номера 0, 1 и 2 у каждого процесса заняты входом, выводом и выводом ошибок. Поэтому у сборщика 64 дескриптора: 61 журнал и три стандартных потока. Каталог /proc/<PID>/fd — список этих номеров, и читать его можно только у своих процессов: у чужих — через sudo.
У каждого процесса есть набор лимитов: сколько файлов он держит открытыми, сколько процессов запускает, какого размера файл пишет. Открыть файл сверх лимита ядро не даёт: оно возвращает ошибку EMFILE, а программа печатает её текст — Too many open files.
Лимиты живого процесса лежат в /proc/<PID>/limits, и этот файл читает любой пользователь:
Лимиты процесс получает от родителя в момент запуска. Твоя оболочка получила свои при входе, и всё, что ты из неё запускаешь, начинает с них. Сборщика запустил systemd, поэтому твои 1024 к нему не относятся.
Ты понизил в своей оболочке лимит открытых файлов до 100 (ulimit -n 100), а потом запустил из неё python3. Сколько файлов сможет держать открытыми python3?
-
64 стоит у процесса сборщика, которого запустил systemd. python3 берёт лимиты у оболочки, из которой запущен.
-
Своего значения по умолчанию у процесса нет: при запуске он копирует лимиты родителя, а родитель здесь — оболочка с лимитом 100.
Процесс получает лимиты родителя в момент запуска, поэтому у python3 тот же лимит 100. Проверить можно в подоболочке, не задевая свою: (ulimit -n 100; grep 'open files' /proc/self/limits) — у grep в строке Max open files стоит 100.
Главное в шаге
- Открытый файл для процесса — дескриптор; 0, 1 и 2 заняты стандартными потоками.
- Сверх лимита ядро файл не открывает: программа получает EMFILE и пишет Too many open files.
-
Лимиты процесс копирует у родителя при запуске; живые значения — в
/proc/<PID>/limits.