Правильное поведение демона (из PEP 3143) объяснено
У меня есть несколько задач [для моего RPi] в Python, которые включают в себя много sleep
ing: сделайте что-то, что займет секунду, две или три, затем подождите несколько минут или часов. Я хочу передать управление обратно ОС (Linux) в это время сна. Для этого я должен демонизировать эти задачи. Одним из способов является использование стандартной библиотеки процессов Python-процесса.
Но демонов не так легко понять. Согласно параграфу "Обоснование" в PEP 3143, демон с хорошим поведением должен делать следующее.
- Закройте все открытые файловые дескрипторы.
- Изменить текущий рабочий каталог.
- Сбросьте маску создания доступа к файлу.
- Запустите в фоновом режиме.
- Отсоединиться от группы процессов.
- Игнорировать сигналы ввода-вывода терминала.
- Отсоединить от терминала управления.
- Не приобретайте контрольный терминал.
- Правильно обработайте следующие обстоятельства:
- Запущен процессом инициализации System V.
- Завершение демона по сигналу SIGTERM.
- Дети генерируют сигнал SIGCLD.
Для начинающих пользователей Linux/Unix, таких как я, это вряд ли можно объяснить. Но я хочу знать, почему я делаю то, что делаю. Так что же стоит за этим обоснованием?
1 ответ
PEP 3142 взял эти требования от сетевого программирования Unix ("UNP") покойного У. Ричарда Стивенса. Приведенное ниже объяснение цитируется или обобщается из этой книги. Это не так легко найти в Интернете, и это может быть незаконным для загрузки. Поэтому я позаимствовал его в библиотеке. Упомянутые страницы находятся во втором издании, том 1 (1998). (ОПТОСОЗ относится к первому изданию, 1990 г.)
Закройте все открытые файловые дескрипторы.
"Мы закрываем все открытые дескрипторы, унаследованные от процесса, который выполнял демон (то есть оболочку). [..] Некоторые открытые демоны
/dev/null
для чтения и записи и дублирования дескриптора для стандартного ввода, стандартного вывода и стандартной ошибки."
(Этот демон Python 'Howdy World' демонстрирует это.)
"Это гарантирует, что общие дескрипторы открыты, и чтение из любого из этих дескрипторов возвращает 0 (конец файла), и ядро просто отбрасывает все, что записано в любой из этих трех дескрипторов. Причина открытия этих дескрипторов заключается в том, что любая библиотека Функция, вызываемая демоном, которая предполагает, что она может читать из стандартного ввода или записывать в стандартный вывод или в стандартную ошибку, не завершится с ошибкой. Альтернативно, некоторые демоны открывают файл журнала, в который они будут записывать во время работы, и дублируют его дескриптор на стандартный вывод и стандарт ошибка". (UNP стр. 337)
Изменить текущий рабочий каталог
"Демон принтера может перейти в каталог спулинга принтера, где он выполняет всю свою работу. [...] Демон мог быть запущен где-нибудь в файловой системе, и если он там останется, эту файловую систему нельзя отключить". (UNP, стр. 337)
Почему вы хотите размонтировать файловую систему? Две причины:
1. Вы хотите отделить (и иметь возможность монтировать и размонтировать) каталоги, которые могут заполняться пользовательскими данными из каталогов, предназначенных для ОС.
2. Если вы запускаете демон, скажем, с USB-флешки, вы хотите иметь возможность размонтировать эту флешку, не мешая демону.
Сбросьте маску создания доступа к файлу.
"Таким образом, если демон создает свои собственные файлы, биты разрешений в маске создания режима наследуемого файла не влияют на биты разрешений новых файлов". (UNP, стр. 337)
Запустите в фоновом режиме.
По определению,
"демон - это процесс, который работает в фоновом режиме и не зависит от управления всеми терминалами". (UNP p 331)
Отсоединиться от группы процессов.
Чтобы понять это, вам нужно понять, что такое группа процессов, а это значит, что вам нужно знать, что fork
делает.
Что делает вилка
fork
это единственный способ (в Unix) создать новый процесс. (в Linux также есть clone
). Ключ в понимании fork
является то, что он возвращается дважды при вызове (один раз): один раз в вызывающем процессе (= parent) с идентификатором процесса вновь созданного процесса (= child) и один раз в дочернем."Все дескрипторы, известные родителю при разветвлении, передаются потомку при возврате fork". (UNP стр. 102). Когда процесс хочет выполнить другую программу, он создает новый процесс, вызывая fork, который создает свою копию. Затем один из них (обычно ребенок) вызывает новую программу. (UNP, стр. 102)
Зачем отрываться от группы процессов
Дело в том, что лидер сеанса может получить управляющий терминал. Демон никогда не должен этого делать, он должен оставаться на заднем плане. Это достигается путем вызова fork
дважды: родитель разветвляет, чтобы создать ребенка, ребенок разветвляет, чтобы создать внука. Родитель и ребенок уволены, но внук остается. Но поскольку это внук, это не лидер сеанса, и поэтому он не может приобрести управляющий терминал. (Суммировано из UNP пар 12.4 с 335)
Двойная вилка обсуждается более подробно здесь и в комментариях ниже.
Игнорировать сигналы ввода-вывода терминала.
"Сигналы, генерируемые ключами терминала, не должны влиять на любые демоны, запущенные с этого терминала ранее". (UNP стр. 331)
Отсоединитесь от терминала управления и не возвращайте терминал управления.
К настоящему времени причины очевидны:
"Если демон запускается из терминала, мы хотим иметь возможность использовать этот терминал для других задач позднее. Например, если мы запустим демон из терминала, выйдем из терминала, а кто-то еще войдет в систему. этот терминал, мы не хотим, чтобы какие-либо сообщения об ошибках демона появлялись во время сеанса терминала следующего пользователя." (UNP p 331)
Правильно обработайте следующие обстоятельства:
Запущен процессом инициализации System V
- Очевидно, демон должен запускаться во время загрузки.
Завершение демона сигналом SIGTERM
- SIGTERM означает прекращение сигнала. При выключении процесс init обычно отправляет SIGTERM всем процессам, обычно ждет от 5 до 20 секунд, чтобы дать им время на очистку и завершение работы. (UNP, стр. 135) Кроме того, ребенок может отправить SIGTERM своему родителю, когда его родитель должен прекратить делать то, что он делает. (UNP p 408)
Дети генерируют сигнал SIGCLD
- Стивенс обсуждает SIGCHLD, а не SIGCLD. Разница между ними не важна для понимания поведения демона. Если ребенок завершает работу, он отправляет SIGCHLD своему родителю. Если родитель не ловит его, ребенок становится зомби (UNP p 118). Ох, как весело.
В заключение, когда я начал находить ответы на свой вопрос в UNP, вскоре меня поразило, что я действительно должен прочитать больше. Это более 900 (!) Страниц, начиная с 1998 года (!), Но я считаю, что концепции и объяснения в UNP прекрасно выдерживают испытание временем. Стивенс не только очень хорошо знал, о чем говорит, он также понимал, что в этом сложного, и облегчал понимание. Это действительно редко.