Daemonize (демонизация) — системная операция, переводящая процесс из интерактивного режима в фоновый: процесс отвязывается от управляющего терминала и продолжает работу после завершения пользовательской сессии. Так работают веб-серверы, базы данных, планировщики задач и любой серверный фоновый процесс.
Алгоритм классической демонизации (double-fork)
Классический алгоритм double-fork в POSIX-системах:
- Первый fork() — родительский процесс завершается; дочерний продолжает работу. Родитель отдаёт управление оболочке, дочерний получает нового родителя (init/PID 1).
- setsid() — дочерний вызывает setsid(), создавая новую сессию без управляющего терминала.
- Второй fork() — гарантирует, что демон не является лидером сессии и не может повторно получить управляющий терминал.
- Смена рабочего каталога —
chdir("/"), чтобы не блокировать размонтирование файловых систем. - Перенаправление дескрипторов — stdin, stdout, stderr закрываются или перенаправляются на
/dev/null. - PID-файл — демон записывает свой PID в
/var/run/daemon.pid.
Демонизация через системную библиотеку
Функция daemon(3) (glibc) выполняет double-fork автоматически:
#include <unistd.h>
int main() {
if (daemon(0, 0) == -1) {
perror("daemon");
return 1;
}
while (1) {
do_work();
sleep(1);
}
}
Первый аргумент 0 — сменить рабочий каталог на /. Второй 0 — перенаправить stdin/stdout/stderr на /dev/null.
Демонизация через systemd
В современных Linux-системах с systemd ручная демонизация не нужна. Достаточно описать сервис в unit-файле с Type=simple:
[Unit]
Description=My Background Service
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/myservice
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
При Type=forking systemd ожидает завершения родительского процесса (классический double-fork) и отслеживает PID через PIDFile=.
Способы демонизации
- Классический double-fork — ручная реализация через
fork()иsetsid(). - Функция
daemon(3)— стандартная glibc-функция, выполняет double-fork одной строкой. - start-stop-daemon — утилита из пакета
dpkg. Запускает процесс как демон, создаёт PID-файл. - systemd — программа не обязана демонизироваться сама; systemd берёт на себя управление.
- Supervisor — менеджер процессов для Python-приложений без native daemon support.
- PM2 — аналог Supervisor для Node.js.
История
Термин «daemon» ввёл Фернандо Корбато (Fernando Corbato) в MIT в 1963 году для системы CTSS — по аналогии с демоном Максвелла из термодинамики. В Version 7 Unix (1979) появился стандартный набор демонов: cron, inetd, lpd. Функция daemon(3) стандартизирована в POSIX.1-2001. С распространением systemd (с 2012 года в Fedora, с 2015 в Debian/Ubuntu) необходимость ручного double-fork резко снизилась.
Диагностика демонов в хостинге
На VDS и выделенных серверах демонизация критична для любого фонового сервиса. Nginx, MySQL, Redis работают как системные демоны под управлением systemd. На виртуальном хостинге запускать демонов нельзя — нет доступа к fork() и управлению процессами. При отладке: journalctl -u имя.service -f — логи в реальном времени; systemctl status имя.service — состояние, дата последнего рестарта, код выхода при ошибке; systemd-analyze blame — время запуска каждого демона при старте системы.
Особенности демонизации в контейнерах
В Docker-контейнерах концепция демонизации работает иначе. Контейнер рассчитан на запуск одного переднепланового процесса (PID 1). Если процесс демонизируется и родитель завершается, Docker считает контейнер остановленным. Рекомендация: запускать сервис без демонизации (nginx -g "daemon off;", mysqld --nodaemonize) — Docker сам управляет жизненным циклом через механизм restart policy (--restart=always).