Unix - статьи



         

Демоны - часть 3


Делается это для того чтобы процесс-демон отключился от управляющего терминала. С каждым терминалом Unix связан набор групп процессов, именуемый сессией. В каждый момент времени только одна из групп процессов, входящих в сессию, имеет доступ к терминалу (то есть, может выполнять ввод/вывод с помощью терминала). Эта группа именуется foreground (приоритетной). В каждой сессии есть процесс-родоначальник, который называется лидером сессии. Если процесс-демон запущен с консоли, он, естественно, становится частью приоритетной группы процессов, входящих в сессию соответствующего терминала.

Для того чтобы отключиться от терминала, демон должен начать новую сессию, не связанную с каким-либо терминалом. Для того чтобы демон мог начать новую сессию, он сам не должен быть лидером какой-либо другой сессии. Вызов fork() создает дочерний процесс, который заведомо не является лидером сессии. Далее дочерний процесс, полученный с помощью fork(), начинает новую сессию с помощью вызова функции setsid(2). При этом процесс становится лидером (и единственным участником) новой сессии. if(setsid()

Итак, на данном этапе мы имеем процесс, не связанный с каким-либо терминалом. Далее в некоторых руководствах рекомендуется вызвать fork() еще раз, чтобы новый процесс перестал быть лидером новой сессии (в System V лидер сессии может автоматически получить управляющий терминал при некоторых условиях). В Linux в повторном вызове fork() нет необходимости и мы его делать не будем.

Стоит отметить, что теперь наш демон получил новый PID, который мы снова должны записать в pid-файл демона. Мы записываем значение PID в файл в строковом виде (а не как переменную типа pid_t). Делается это для удобства пользователя, чтобы значение PID из pid-файла можно было прочитать с помощью cat. Например: kill `cat /var/run/aahzd.pid `

Нашему демону удалось разорвать связь с терминалом, с которого он был запущен, но он все еще может быть связан с другими процессами и файловыми системами через файловые дескрипторы, унаследованные от родительских процессов. Для того чтобы разорвать и эту связь, мы закрываем все файловые дескрипторы, открытые в нашем процессе: numFiles = sysconf(_SC_OPEN_MAX); for(i = numFiles-1; i >= 0; --i) { if(i != lockFD) close(i); }




Содержание  Назад  Вперед