Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.
Если ты профессионал (или хочешь им стать) он не понимаешь важных вещей то надо немедленно прочитать книжку. Благо есть на русском очень хорошая. Стевенс "unix: взаимодействие процессов"
Здравствуйте, Force_Majeure, Вы писали:
F_M>Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.
Команда service stop SRV просто вызывает скрипт /etc/init.d/SRV с параметром stop. А уж этот скрипт выполняет соответствующее действие (которое зависит от самого сервиса), например, "киляет" процесс по его PID, выполняя что-то вроде kill `pgrep SRV`. Посмотрите тексты скриптов из каталога /etc/init.d/.
Здравствуйте, fefelov, Вы писали:
F>Здравствуйте, Force_Majeure, Вы писали:
F_M>>Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.
F>Команда service stop SRV просто вызывает скрипт /etc/init.d/SRV с параметром stop. А уж этот скрипт выполняет соответствующее действие (которое зависит от самого сервиса), например, "киляет" процесс по его PID, выполняя что-то вроде kill `pgrep SRV`. Посмотрите тексты скриптов из каталога /etc/init.d/.
т.е. получается, что "общаться" с демоном можно только передавая ему сигналы, а внутри него переопределяя обработчики этих сигналов? Есть-ли какой-то дипазон сигналов, предназначенный для пользовательских нужд или для этого нужно использовать системные?
Здравствуйте, Force_Majeure, Вы писали:
F_M>т.е. получается, что "общаться" с демоном можно только передавая ему сигналы, а внутри него переопределяя обработчики этих сигналов? Есть-ли какой-то дипазон сигналов, предназначенный для пользовательских нужд или для этого нужно использовать системные?
Здравствуйте, fefelov, Вы писали:
F>Не только. Посмотрите, например, здесь: F>
F>8. Средства межпроцессного взаимодействия
F>Рассматриваются средства локального межпроцессного взаимодействия — каналы, сигналы, очереди сообщений, семафоры, разделяемые сегменты памяти.
У всех этих ipc (очереди сообщений, семафоры, разделяемые сегменты памяти) есть плохие моменты:
— они не удаляются после аварийного завершения процесса (или если процесс "забыл" из удалить). Приходится их потом чистить ipсrm.
— они конечны (нужно подкручивать sysctl или /proc чтоб на все хватало)
По этому если ничего специального не надо, лучше обойтись двумя вещами:
1. Сигнал — это просто пнуть процесс. Просто и дешего .
2. unix socket — это уже полноценный канал управления.
Здравствуйте, aka50, Вы писали:
A>Здравствуйте, fefelov, Вы писали:
F>>Не только. Посмотрите, например, здесь: F>>
F>>8. Средства межпроцессного взаимодействия
F>>Рассматриваются средства локального межпроцессного взаимодействия — каналы, сигналы, очереди сообщений, семафоры, разделяемые сегменты памяти.
A>У всех этих ipc (очереди сообщений, семафоры, разделяемые сегменты памяти) есть плохие моменты: A>- они не удаляются после аварийного завершения процесса (или если процесс "забыл" из удалить). Приходится их потом чистить ipсrm. A>- они конечны (нужно подкручивать sysctl или /proc чтоб на все хватало)
A>По этому если ничего специального не надо, лучше обойтись двумя вещами: A>1. Сигнал — это просто пнуть процесс. Просто и дешего . A>2. unix socket — это уже полноценный канал управления.
Похоже действительно оптимальный путь — создать сокет и через него командами управлять демоном.
Здравствуйте, Force_Majeure, Вы писали:
F_M>Здравствуйте, aka50, Вы писали:
A>>2. unix socket — это уже полноценный канал управления.
F_M>Похоже действительно оптимальный путь — создать сокет и через него командами управлять демоном.
Более того, это еще и безопасно. В обработчике сигналов можно только атомарные и реентрабельные (с возможностью
повторного входа) функции использовать можно. По этому я обычно делал так:
#define SIGSOCK_WRFD 0
#define SIGSOCK_RDFD 1
int g_sigsock[2]; // это можно при старте сосздать как socketpair(AF_UNIX ...)
//где-то в main()
{
socketpair(AF_UNIX, SOCK_DGRAM, 0, g_sigsock); // можно и SOCK_STREAM, но если буфер переполнится
// можно в send() заблокироваться. А он там не большой (вроде
// 32к в FreeBSD... точно уже не помню)
}
sig_handler(int sig)
{
case SIGHUP:
send(g_sigsock[SIGSOCK_RDFD], "H", 1, 0);
break;
....
}
// где-то в коде через select или просто в блокирующем режимe
// в другой нити
{
char sigchar[1];
int rc = recv(g_sigsock[1], sigchar, 1, 0);
if (rc // ошибка можно завершаться ;) )
...
switch (sigchar[0])
{
case'H':
// тут пинаем другие потоки или еще что-то делаем чтобы обработать HUP
}
}
Помимо разных бонусов это еще позволяет сериализовать поступающие сигналы и не получить
какойнибудь UB.