2010-06-22 3 views
44

Я пишу демона Linux. Я нашел два способа сделать это.Linux daemonize

  1. демон ваш процесс с помощью вызова fork() и установки sid.
  2. Запуск программы с помощью &.

Какой правильный способ сделать это?

+1

Вы можете использовать nohup: http://stackoverflow.com/questions/958249/whats-the-difference-between-nohup-and-a-daemon – rogerdpack

ответ

76

От http://www.steve.org.uk/Reference/Unix/faq_2.html#SEC16

Вот шаги, чтобы стать демоном:

  1. вилка(), так что родитель может выйти, это возвращает управление в командной строке или оболочки, ссылающегося программу. Этот шаг необходим, чтобы гарантировать, что новый процесс не будет лидером группы процессов. Следующий шаг, setsid(), терпит неудачу, если вы лидер группы процессов.
  2. setsid(), чтобы стать группой процессов и лидером группы сеансов. Поскольку управляющий терминал связан с сеансом, и этот новый сеанс еще не приобрел контрольный терминал, наш процесс теперь не имеет управляющего терминала, что является хорошим типом для демонов.
  3. fork() снова, так что родительский (лидер группы сеансов) может выйти. Это означает, что мы, как лидер несетевой группы, никогда не сможем восстановить контрольный терминал.
  4. chdir ("/"), чтобы гарантировать, что наш процесс не сохранит никакой каталог. Невозможность сделать это может привести к тому, что администратор не сможет отключить файловую систему, потому что это был наш текущий каталог. [Эквивалентно, мы могли бы перейти на любой каталог, содержащий файлы, важные для работы демона.]
  5. umask (0), чтобы мы имели полный контроль над разрешениями всего, что мы пишем. Мы не знаем, что umask мы могли унаследовать. [Этот шаг не является обязательным]
  6. close() fds 0, 1 и 2. Это освобождает стандартную входную, выходную и ошибку, которые мы унаследовали от нашего родительского процесса. У нас нет способа узнать, куда эти фоны могли быть перенаправлены. Обратите внимание, что многие демоны используют sysconf() для определения предела _SC_OPEN_MAX. _SC_OPEN_MAX сообщает вам максимальные открытые файлы/процесс. Затем в цикле демон может закрыть все возможные файловые дескрипторы. Вы должны решить, нужно ли вам это делать или нет. Если вы считаете, что файловые дескрипторы могут открываться, вы должны закрыть их, так как существует ограничение на количество параллельных дескрипторов файлов.
  7. Установите новые открытые дескрипторы для stdin, stdout и stderr. Даже если вы не планируете использовать их, все же рекомендуется открыть их.Точное обращение с ними - дело вкуса; если у вас есть файл журнала, например, вы можете открыть его как stdout или stderr и открыть '/ dev/null' как stdin; альтернативно, вы можете открыть '/ dev/console' как stderr и/или stdout, а '/ dev/null' в качестве stdin или любую другую комбинацию, которая имеет смысл для вашего конкретного демона.

еще лучше, просто вызовите функцию daemon(), если он доступен.

+1

вам нужно закрыть все открытые дескрипторы. В противном случае файлы могут продолжать иметь ссылку, которая, например, предотвратит их удаление. Это похоже на chdir ("/"). –

+2

@ n-alexanderso - это демона() двойные вилки? – Dannyboy

+1

Хороший пример на Ruby WEBrick daemonize (toggle source): http://ruby-doc.org/stdlib-2.1.1/libdoc/webrick/rdoc/WEBrick/Daemon.html –

2

На самом деле, чтобы сделать демона, вам нужно удвоить вилку.

Запуск программы с помощью & заставляет оболочку запускать программу в фоновом режиме, что не делает ее демоном. У демонов есть init (pid 1) как родитель, поэтому нужна двойная вилка.

Таким образом, хороший способ сделать что-либо, если ваша программа является демоном, - это позаботиться об этой проблеме самостоятельно (есть и другие методы, см. Также here). Вы также можете использовать программу start-stop-daemon.

5

Первый. Второе не демонамизирует, а работает на фоне. Демонстрированные программы должны быть на собственной сессии и в группе процессов, а в нет имеют управляющий терминал.

+1

, но я все еще не могу понять, что такое использование собственной сессии и группе процессов – Poorna

2

Какой язык вы используете? На некоторых языках есть вспомогательные методы, которые упрощают демонтаж. Например, Ruby имеет пакет daemons.

+0

Мы используем C++ – Poorna

11

Просто используйте daemon(3) (от unistd.h).

Функция демон() для программ желающих отделиться от управляющего терминала и запустить в фоновом режиме в качестве системных демонов. ...

+0

Я провел несколько дней, исследуя, как я могу запускать фляжное приложение в качестве демона на ubuntu, используя jenkins, пока не увижу ваш совет. Спасибо! Моя проблема решена с помощью команды оболочки 'export BUILD_ID = dontKillMe' ' daemon flask run' – barbarian

28

Предлагаю не писать вашу программу как демон вообще. Запустите его на переднем плане с файловыми дескрипторами, текущим каталогом, группой процессов и т. Д.

Если вы хотите запустить эту программу в качестве демона, используйте start-stop-daemon (8), init (8), runv (из runit), upstart, systemd или что-то другое, чтобы запустить ваш процесс в качестве демона , То есть, пусть ваш пользователь решает, как запустить вашу программу, и не принуждать ее выполнять как демон.

+6

+1. По крайней мере, предложите вариант для запуска на переднем плане. –

+0

Извините, что принесли старый ответ, но monit может запустить ваш процесс как демон? – allaire

Смежные вопросы