Как работает DAEMON(3)? Запуск в фоновом режиме

Как работает DAEMON(3)? Запуск в фоновом режиме

Какие шаги нужно сделать, чтобы процесс отсоединился от терминала? Для этого я нашел страницу руководстваdaemon()В описании они упомянули

Если nochdir равен нулю, daemon() изменяет текущий рабочий каталог процесса на корневой каталог ("/"); в противном случае текущий рабочий каталог остается неизменным.

Если noclose равен нулю, daemon() перенаправляет стандартный ввод, стандартный вывод и стандартную ошибку в /dev/null; в противном случае никакие изменения в эти файловые дескрипторы не вносятся.

На самом деле, я пытался заставить свой код Python работать как демон. Я нашел tcollectorкодздесь. В этом коде они также следуют тем же шагам, что и в описании daemon(). Поэтому мой вопрос в том, почему мы должны делать эти шаги (по сравнению сdaemonize()в tcollector) нравится

зачем менять dirна /, umaskна 022, а затем звонить os.setsid()и т. д.

решение1

На самом деле там больше информации, чем вы процитировали, но я думаю, что эта страница руководства могла бы быть более понятной.

Если nochdir равен нулю, daemon()изменяет текущий рабочий каталог процесса на корневой каталог ( /)

Здесь предполагается, что программа запускается из командной строки администратора, и идея состоит в том, чтобы отсоединить демон от того, что администратор делал в это время. Изменение рабочего каталога на /не позволяет демону держать точку монтирования занятой. Например, если рабочий каталог был /home/adminи некоторое время спустя вы хотите размонтировать /home, демон предотвратит это.

Если noclose равен нулю, daemon()перенаправляет стандартный ввод, стандартный вывод и стандартную ошибку в /dev/null;

Это сделано для того, чтобы демон не сбивал с толку пользователей, записывая случайные сообщения об ошибках или что-то подобное на их терминал. Что демон, вероятно, должен сделать, так это открыть какой-нибудь (настроенный) файл журнала и записать туда все, что он хочет сообщить наружу.

(Эта функция разветвляется, и если fork(2) завершается успешно, родитель вызывает _exit(2), так что дальнейшие ошибки видны только потомку.)

Опять же, чтобы отключиться от сеанса оболочки администратора, основная программа немедленно возвращается, а другая часть остается в фоновом режиме, поэтому нет необходимости явно запрашивать запуск программы в фоновом режиме (например, ./daemon &)

Теперь то, о чем страница руководства явно не говорит, но подразумевает здесь (в разделе ОШИБКИ):

Реализация этой функции в библиотеке GNU C была взята из BSD и не использует технику двойного ветвления (т. е. fork(2), setsid(2), fork(2)), необходимую для того, чтобы гарантировать, что полученный процесс-демон не является лидером сеанса. Вместо этого полученный демон является лидером сеанса.

daemon()также звонкиsetsid()освободить себя от сеансауправляющий терминал, и, следовательно, из сигналов, посылаемых терминалом. Но как говорится в цитате, это оставляет возможность того, что если он открывает терминальное устройство, он может случайно получить его в качестве управляющего терминала вместо этого. Чтобы избежать этого, некоторые программы вызывают fork(), затем setsid()из дочернего процесса, а затем снова разветвляются, выходя из обоих родителей, так что полученный процесс не является лидером сеанса (средний является/был), и не может получить управляющий терминал. Программа Python, на которую вы ссылаетесь, делает именно это.

Изменение umaskне похоже на то, чтобы быть связанным с демонизацией. Возможно, эта программа имеет особую потребность в этом.

Связанный контент