Как порождать дочерние процессы, которые не умирают вместе с родителями?

У меня есть программа на C ++, которая работает над другими. Если он обнаруживает, что процесс больше не работает, он перезапускает его через system, Проблема в том, что если я убью сторожевой процесс, все запущенные процессы также умрут.

void* ProcessWatchdog::worker(void* arg)
{
//Check if process is running
if( !processRunning )
system("processName /path/to/processConfig.xml &");
}

Новый дочерний процесс запускается правильно и работает без проблем. Но когда родитель (теперь этот ProcessWatchdog умирает, ребенок тоже умирает. Как я могу порождать дочерний процесс, который полностью независим от родителя?

Я пытался использовать pclose а также popenзапуск сценариев оболочки, запускающих процессы, и несколько других тактик, но безрезультатно. Я игнорирую SIGHUP сигналы в дочерних процессах, но они все равно умирают.

В идеале, я бы хотел сказать системе запустить процесс, который полностью независим от родителя. Я хочу ребенка trace покончить с ребенком, и чтобы он / система не знали, что ProcessWatchdog начал это в первую очередь.

Есть ли способ, которым я могу сделать это?

Я пишу это на C ++, на Linux.

5

Решение

Попробуйте использовать system с setsid перед именем процесса.

system("setsid processname /path/to/processConfig.xml &");

Это запустит программу в новом сеансе.

0

Другие решения

Этот немного староват, но не получил полного ответа. Вот что я сделал во встроенной системе, чтобы создать дочерний элемент bash, не имеющий отношения к родительскому. Обратите внимание, что я запускаю оболочку bash, а затем запускаю команду в другой оболочке bash. Это не может быть необходимым в вашей ситуации. Для меня это позволило мне сделать некоторое перенаправление ввода / вывода, которое не работало должным образом без него.

Двумя важными понятиями являются setsid () и double fork (). Комбинация этих двух препятствует созданию зомби, когда ребенок-сирота завершает свою работу, а также предотвращает убийство ребенка-сироты, если родитель завершает свою работу.

Существует много других проблем, таких как унаследованные дескрипторы ввода-вывода, рабочий каталог и т. Д., Но этот код выполняет основную работу.

int spawn_orphan(char* cmd) {
char command[1024]; // We could segfault if cmd is longer than 1000 bytes or so
int pid;
int Stat;
pid = fork();
if (pid < 0) { perror("FORK FAILED\n"); return pid; }
if (pid == 0) { // CHILD
setsid(); // Make this process the session leader of a new session
pid = fork();
if (pid < 0) { printf("FORK FAILED\n"); exit(1); }
if (pid == 0) { // GRANDCHILD
sprintf(command,"bash -c '%s'",cmd);
execl("/bin/bash", "bash", "-c", command, NULL); // Only returns on error
perror("execl failed");
exit(1);
}
exit(0); // SUCCESS (This child is reaped below with waitpid())
}

// Reap the child, leaving the grandchild to be inherited by init
waitpid(pid, &Stat, 0);
if ( WIFEXITED(Stat) && (WEXITSTATUS(Stat) == 0) ) {
return 0; // Child forked and exited successfully
}
else {
perror("failed to spawn orphan\n");
return -1;
}
}
4

Не использовать system(...) это не многопоточность безопасно.

int pid = fork();

if(pid==0)
{
int rc = execv("processname", "/path/to/processConfig.xml &");
if(rc == -1)
{
printf(stderr, "processname failed to start. %d", errno);
}
...
}
else
{
//continue with the parent
}
3

Вы должны избегать использования системы.

Не используйте system () из программы с set-user-ID или set-group-ID
привилегии, потому что странные значения для некоторых переменных среды
может быть использован для нарушения целостности системы. Используйте семейство exec (3)
функции вместо

а также, если вы хотите проверить возвращаемое значение или что-нибудь еще

Просто пойти на execl

#include <unistd.h>
#include <stdlib.h>
pid_t pid = fork()
if (pid == -1)
{
exit(EXIT_FAILURE);
}
else if (pid == 0)
{
if (execl("processname", "processname", "/path/to/processConfig.xml", NULL) == -1)
exit(EXIT_FAILURE);
}
else
...
1

Вы можете быть заинтересованы демон (3) функция библиотеки (внутренне используя два вложенных вилка (2) Системные вызовы). После этого используйте соответствующие execve (2) системный вызов (или связанный Exec (3) функции) …

Вы должны прочитать Расширенное программирование в Linux для большего.

0

Есть пример execvp в https://github.com/w-A-L-L-e/wash/blob/master/src/wash.cpp. Передача аргументов командной строки иногда является проблемой с функциями exec * от unistd, и передача среды может быть некоторой работой. В любом случае, надеюсь, это поможет …

0
По вопросам рекламы [email protected]