Ссылка для правильной обработки файла PID в Unix - PullRequest
58 голосов
/ 27 марта 2009

Где я могу найти уважаемую ссылку , которая подробно описывает правильную обработку файлов PID в Unix?

В операционных системах Unix обычной практикой является «блокировка» программы (часто демона) с помощью специального файла блокировки: файла PID.

Это файл в предсказуемом месте, часто "/var/run/foo.pid". Предполагается, что программа при запуске проверяет, существует ли файл PID, и, если файл существует, завершается с ошибкой. Так что это своего рода консультативный механизм коллективной блокировки.

Файл содержит одну строку текста, представляющую собой числовой идентификатор процесса (отсюда и название «файл PID») процесса, который в данный момент удерживает блокировку; это позволяет легко автоматизировать отправку сигнала процессу, который удерживает блокировку.

То, что я не могу найти, является хорошим справочником по ожидаемому или «оптимальному» поведению при работе с файлами PID. Существуют различные нюансы: как на самом деле заблокировать файл (не беспокоиться? Использовать ядро? Как насчет несовместимости платформ?), Обрабатывать устаревшие блокировки (безмолвно удалять их? Когда проверять?), Когда именно получить и снять блокировку и т. д.

Где можно найти уважаемую, наиболее авторитетную ссылку (в идеале на уровне В. Ричарда Стивенса) для этой небольшой темы?

Ответы [ 5 ]

21 голосов
/ 27 марта 2009

Во-первых, на всех современных UNIX /var/run не сохраняется при перезагрузках.

Общий метод обработки файла PID состоит в том, чтобы создать его во время инициализации и удалить его из любого выхода, либо обычного, либо обработчика сигнала.

Существует два канонических способа атомарного создания / проверки файла. Основным в наши дни является его открытие с флагом O_EXCL: если файл уже существует, вызов не выполняется. Старый способ (обязательный для систем без O_EXCL) - создать его со случайным именем и ссылкой на него. Ссылка не будет выполнена, если цель существует.

17 голосов
/ 27 марта 2009

Насколько мне известно, PID-файлы - это соглашение, а не то, что вы можете найти уважаемый, в основном авторитетный источник. Самое близкое, что я мог найти, это этот раздел стандарта иерархии файловых систем.

Эта библиотека Perl может оказаться полезной, поскольку похоже, что автор хотя бы задумался над некоторыми проблемами, которые могут возникнуть.

Я полагаю, что файлы в / var / run часто обрабатываются сопровождающими дистрибутива, а не авторами демонов, так как ответственные за дистрибутив отвечают за то, чтобы все сценарии инициализации хорошо играли вместе. Я проверил документацию для разработчиков Debian и Fedora и не смог найти подробных рекомендаций, но вы можете получить больше информации в списках рассылки их разработчиков.

11 голосов
/ 30 ноября 2012

См. Kerrisk Интерфейс программирования Linux , раздел 55.6 "Запуск всего одного экземпляра программы" , основанный на реализации pidfile в Unix Network Programming Стивенса, версия 2.

Обратите также внимание, что расположение pid-файла обычно обрабатывается дистрибутивом (через скрипт init), поэтому хорошо написанный демон примет аргумент командной строки для указания pid-файла и не допустит случайного изменения этого файла конфигурационный файл. Он также должен изящно обрабатывать устаревший файл pid (O_EXCL не должен использоваться). Следует использовать блокировку файлов fcntl () - вы можете предположить, что pid-файл демона находится в локальной (не NFS) файловой системе.

7 голосов
/ 27 марта 2009

В зависимости от дистрибутива, это фактически скрипт инициализации, который обрабатывает pid-файл. Он проверяет существование при запуске, удаляет при остановке и т. Д. Мне не нравится делать это таким образом. Я пишу свои собственные сценарии инициализации и обычно не использую стандартные функции инициализации.

Хорошо написанная программа (демон) будет иметь какой-то файл конфигурации, в котором будет указано, где должен быть записан этот pid-файл (если есть). Он также позаботится о том, чтобы установить обработчики сигналов, чтобы файл PID очищался при нормальном или ненормальном выходе при любой обработке сигнала. Затем файл PID дает сценарию инициализации правильный PID, чтобы его можно было остановить.

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

Что касается пространства имен, оно должно следовать за именем программы. Если вы запускаете 'foo-daemon', это будет foo-daemon.pid

Вам также следует изучить / var / lock / subsys, однако он используется в основном в версиях Red Hat.

1 голос
/ 04 апреля 2018

Пакет systemd в Red Hat 7 предоставляет справочную страницу daemon(7) со строкой заголовка «Написание и сборка системных демонов».

На этой странице руководства обсуждается демонизация "старого стиля" (SysV) и "нового стиля" (systemd). В новом стиле systemd сама обрабатывает PID-файлы для вас (если так настроено). Тем не менее, в старом стиле, страница руководства имеет следующее:

  1. В процессе демона напишите PID демона (как возвращено getpid ()) в файл PID, например /run/foobar.pid (для гипотетического демона «foobar»), чтобы демон не мог быть запущен более одного раза. Это должно быть реализовано без гонки, чтобы файл PID обновляется только тогда, когда проверено, что PID ранее сохраненный в файле PID больше не существует или принадлежит чужой процесс.

Вы также можете прочитать эту справочную страницу онлайн .

...