Демоны — это процессы, которые не запускаются непосредственно под контролем пользователя, а работают в фоновом режиме. Обычно они запускаются при запуске системы и работают непрерывно, пока система не выключится. Единственная разница между этими и обычными процессами заключается в том, что они никаким образом не отправляют сообщения на консоль или экран.
Вот как вы можете создать демон на машине с Linux.
Краткое введение в то, как создаются демоны
В системе работает множество демонов, и некоторые знакомые примеры демонов:
- кронд: запускает команды в указанное время
- sshd: Позволяет войти в систему с удаленных компьютеров.
- httpd: Обслуживает веб-страницы
- нфсд: Разрешает обмен файлами по сети.
Кроме того, имена процессов-демонов обычно заканчиваются на букву д, хотя это и не обязательно.
Для запуска процесса в качестве демона следует следующий путь:
- Начальные операции, такие как чтение файлов конфигурации или получение необходимых системных ресурсов, должны быть выполнены до того, как процесс станет демоном. Таким образом, система может сообщить пользователю о полученных ошибках, и процесс будет завершен с соответствующим кодом ошибки.
- Фоновый запущенный процесс создается с инициализацией в качестве родительского процесса. Для этого сначала разветвляется подпроцесс из процесса инициализации, а затем процесс верхнего уровня завершается с выходом.
- Новая сессия должна открываться вызовом функции setsid, а процесс должен быть отключен от терминала.
- Все дескрипторы открытых файлов, унаследованные от родительского процесса, закрываются.
- Стандартный вход, выход, а сообщения об ошибках перенаправляются на /dev/null.
- Рабочий каталог процесса должен измениться.
Что такое сеансы демона?
После входа в систему через терминал пользователи могут запускать многие приложения через программу-оболочку. Эти процессы должны закрываться, когда пользователь выходит из системы. Операционная система группирует эти процессы в группы сеансов и процессов.
Каждый сеанс состоит из групп процессов. Вы можете описать эту ситуацию следующим образом:
Терминал, на котором процессы получают свои входные данные и отправляют свои выходные данные, называется управляющим терминалом. Управляющий терминал одновременно связан только с одним сеансом.
Сеанс и группы процессов в нем имеют идентификационные (ID) номера; эти идентификационные номера являются идентификационными номерами процессов (PID) руководителей сеансов и групп процессов. Дочерний процесс находится в той же группе, что и его родительский процесс. Когда несколько процессов сообщающийся с трубным механизмом, первый процесс становится лидером группы процессов.
Создание процесса демона в Linux
Здесь вы увидите, как можно создать функцию демона. Для этой цели вы создадите функцию с именем _демон. Вы можете начать с того, что назовете код приложения, которое будет работать как демон, как тест.с, и код, в котором вы создадите функцию демона, как демон.c.
//test.c
#включать <stdio.h>
инт_демон(инт, инт);
интглавный()
{
получитьсимвол();
_демон (0, 0);
получитьсимвол();
возврат0;
}
//daemon.c
#включать <sys/types.h>
#включать <sys/stat.h>
#включать <stdlib.h>
#включать <stdio.h>
#включать <fcntl.h>
#включать <unistd.h>
#включать <линукс/fs.h>
#включать <линукс/limits.h>
инт_демон(инт ночдир, инт нет близко){
pid_t идентификатор;
pid = вилка(); // Разветвить родительский процесс
если (пид < 0) {
выход(ВЫХОД_ОШИБКА);
}
если (пид > 0) {
выход(ВЫХОД_УСПЕХ);
}
возврат0;
}
Чтобы создать демон, вам нужен фоновый процесс, родительским процессом которого является init. В приведенном выше коде _демон создает дочерний процесс, а затем убивает родительский процесс. В этом случае ваш новый процесс будет подпроцессом init и продолжит работу в фоновом режиме.
Теперь скомпилируйте приложение с помощью следующей команды и проверьте состояние процесса до и после _деамон называется:
gcc-оконтрольная работаконтрольная работа.сдемон.с
Запустите приложение и переключитесь на другой терминал, не нажимая никаких других клавиш:
./контрольная работа
Вы можете видеть, что значения, относящиеся к вашему процессу, следующие. Здесь вам придется использовать команда ps для получения информации о процессе. В этом случае _демон функция еще не вызывалась.
пс-С контрольная работа -o "pid ppid pgid sid tty статистикакоманда"
# Выход
PID PPID PGID SID TT СТАТ КОМАНДА
10296 5119 10296 5117 б/2 S+ ./контрольная работа
Когда вы смотрите на СТАТИСТИКА поле, вы видите, что ваш процесс запущен, но ожидает возникновения внепланового события, которое заставит его работать на переднем плане.
Сокращение | Значение |
С | Ожидание во сне, чтобы событие произошло |
Т | Приложение остановлено |
с | Лидер сеанса |
+ | Приложение работает на переднем плане |
Вы можете видеть, что родительский процесс вашего приложения, как и ожидалось, является оболочкой.
PS-JP 5119
# Выход
PID PGID SID TTY ВРЕМЯ CMD
5119 5119 5117 оч/2 00:00:02 зш
Теперь вернитесь к терминалу, где вы запускаете свое приложение, и нажмите Войти вызывать _демон функция. Затем снова посмотрите информацию о процессе на другом терминале.
пс-С контрольная работа -o "pid ppid pgid sid tty статистикакоманда"
# Выход
PID PPID PGID SID TT СТАТ КОМАНДА
22504 1 22481 5117 б/2 с./контрольная работа
Во-первых, вы можете сказать, что новый подпроцесс работает в фоновом режиме, так как вы не видите + характер в СТАТИСТИКА поле. Теперь проверьте, кто является родительским процессом процесса, используя следующую команду:
пс-джп 1
# Выход
PID PGID SID TTY ВРЕМЯ CMD
1 1 1? 00:00:01системад
Теперь вы можете видеть, что родительским процессом вашего процесса является системад процесс. Выше упоминалось, что для следующего шага необходимо открыть новую сессию и отключить процесс от терминала управления. Для этого вы используете функцию setsid. Добавьте этот звонок в свой _демон функция.
Кусок кода, который нужно добавить, выглядит следующим образом:
если (setsid() == -1)
возврат-1;
Теперь, когда вы проверили состояние перед _демон называется, теперь вы можете удалить первый получитьчар функция в тест.с код.
//test.c
#включать <stdio.h>
инт_демон(инт, инт);
интглавный()
{
_демон (0, 0);
получитьсимвол();
возврат0;
}
Скомпилировав и снова запустив приложение, перейдите в терминал, где вы делали свои обзоры. Новый статус вашего процесса выглядит следующим образом:
пс-С контрольная работа -o "pid ppid pgid sid tty статистикакоманда"
# Выход
PID PPID PGID SID TT СТАТ КОМАНДА
25494 1 25494 25494? SS ./контрольная работа
? войти в ТТ поле указывает, что ваш процесс больше не подключен к терминалу. Обратите внимание, что ПИД, PGID, и SID значения вашего процесса одинаковы. Теперь ваш процесс является лидером сеанса.
На следующем шаге измените рабочий каталог на корневой в соответствии со значением переданного вами аргумента. Вы можете добавить следующий фрагмент в _демон функция для этого:
если (!ночдир) {
если (чдир("/") == -1)
возврат-1;
}
Теперь по переданному аргументу можно закрыть все файловые дескрипторы. Добавьте следующий код в _демон функция:
#define NR_OPEN 1024
если (!noclose) {
для (я = 0; я < NR_OPEN; я++)
закрыть (я);
открытым("/dev/нулевой", О_RDWR);
дубликат (0);
дубликат (0);
}
После закрытия всех файловых дескрипторов новые файлы, открытые демоном, будут показаны с дескрипторами 0, 1 и 2 соответственно. В этом случае, например, printf команды в коде будут направлены на второй открытый файл. Чтобы избежать этого, первые три идентификатора указывают на /dev/null устройство.
В этом случае конечное состояние _демон функция будет следующей:
#включать <sys/types.h>
#включать <sys/stat.h>
#включать <stdio.h>
#включать <stdlib.h>
#включать <fcntl.h>
#включать <errno.h>
#включать <unistd.h>
#включать <системный журнал.h>
#включать <строка.h>
инт_демон(пустота){
// PID: идентификатор процесса
// SID: идентификатор сеанса
pid_t pid, sid;
pid = вилка(); // Разветвить родительский процесс
если (пид < 0) {
выход(ВЫХОД_ОШИБКА);
}
если (пид > 0) {
выход(ВЫХОД_УСПЕХ);
}
// Создавать а SIDзаребенок
сид = наборы сид();
если (сид < 0) {
// НЕУДАЧА
выход(ВЫХОД_ОШИБКА);
}
если((чдир("/")) < 0) {
// НЕУДАЧА
выход(ВЫХОД_ОШИБКА);
}
закрыть (STDIN_FILENO);
закрыть (STDOUT_FILENO);
закрыть (STDERR_FILENO);
пока (1) {
// Некоторые задачи
сон (30);
}
выход(ВЫХОД_УСПЕХ);
}
Вот пример фрагмента кода, который запускает sshd приложение в качестве демон:
...
if (!(debug_flag || inetd_flag || no_daemon_flag)) {
инт фд;
если (демон (0, 0) < 0)
фатальный("daemon() не удалось: %.200s", strerror (ошибка));
/* Отключение от управляющего tty. */
fd = открыть (_PATH_TTY, O_RDWR | O_NOCTTY);
если (фд >= 0) {
(пустота) ioctl (fd, TIOCNOTTY, NULL);
близко (фд);
}
}
...
Демоны важны для системного программирования Linux
Демоны — это программы, которые выполняют различные действия заранее заданным образом в ответ на определенные события. Они тихо работают на вашем Linux-компьютере. Они не находятся под непосредственным контролем пользователя, и у каждой службы, работающей в фоновом режиме, есть свой демон.
Важно овладеть демонами, чтобы изучить структуру ядра операционной системы Linux и понять работу различных системных архитектур.
Что такое демон?
Читать далее
Похожие темы
- линукс
- Ядро Linux
- Программирование
- Программирование на С
Об авторе
Инженер и разработчик программного обеспечения, фанат математики и технологий. Ему всегда нравились компьютеры, математика и физика. Он разработал проекты игровых движков, а также машинное обучение, искусственные нейронные сети и библиотеки линейной алгебры. Кроме того, продолжает работать над машинным обучением и линейными матрицами.
Подпишитесь на нашу рассылку
Подпишитесь на нашу рассылку технических советов, обзоров, бесплатных электронных книг и эксклюзивных предложений!
Нажмите здесь, чтобы подписаться