убийство дочерних процессов при выходе из родительского процесса

Я очень новичок в c и программировании, и мне нужна помощь. В c on linux (cygwin) мне необходимо удалить все дочерние процессы при выходе. Я просмотрел другие подобные вопросы, но не могу заставить его работать. Я пробовал-

atexit(killzombies); //in parent process

void killzombies(void)
{
    printf("works");
    kill(0, SIGTERM);
    printf("works");
    if (waitpid(-1, SIGCHLD, WNOHANG) < 0)
         printf("works");
}

по какой-то причине «работает» даже никогда не печатается. Я нажимаю ctrl + c, чтобы выйти.

ТАКЖЕ я пробовал-

prctl(PR_SET_PDEATHSIG, SIGHUP); //in child process
signal(SIGHUP, killMe);

void killMe()
{
    printf("works");
    exit(1);
}

но поскольку я использую cygwin, когда я #include <sys/prctl.h>, cygwin говорит, что не может найти файл или каталог, и я не знаю, какой пакет для него установить. Кроме того, если моя функция prctl() сработает, убьет ли это всех зомби?

Моя программа является клиентским сервером, и мой сервер forks() обрабатывает каждого клиента. Я полагаю, что после выключения сервера не останется зомби.


person RileyVanZeeland    schedule 14.09.2012    source источник
comment
Одна ссылка, которую вы можете увидеть faqs.org/faqs/ unix-faq/faq/part3/section-13.html. Особенно последнее решение. Будет ли это работать для вас?   -  person Tanmoy Bandyopadhyay    schedule 14.09.2012


Ответы (3)


Из документации Linux atexit(3):

Функции, зарегистрированные с помощью atexit()on_exit(3)), не вызываются, если процесс аварийно завершается из-за доставки сигнала.

Если вы хотите выполнять очистку, когда ваше приложение получает сигнал SIGINT или SIGTERM, вам необходимо установить соответствующие обработчики сигналов и выполнять свою работу там.

person Sean Bright    schedule 14.09.2012

Ваш waitpid не предоставляет обычные параметры, я удивлен, что он не вылетает. Прототип:

pid_t waitpid(pid_t pid, int *status, int options); 

Второй параметр должен быть указателем на int, вы указываете int. Обратите также внимание, что вы должны вызывать waitpid для каждого дочернего элемента, вы вызываете его только для одного.

atexit() вызывается только при нормальном выходе. Если вы выходите через CTRL+C, вам нужно вызвать вашу функцию из обработчика SIGINT.

person cdarke    schedule 14.09.2012

Вам нужно будет отслеживать, сколько дочерних процессов имеет ваш процесс, а затем вызывать ожидание столько раз. Кроме того, как уже говорили другие, ваша функция atexit() не будет вызываться, если процесс завершается сигналом, поэтому вам также нужно будет вызвать killzombies() из обработчика сигнала. Вам понадобится что-то вроде:

int n_children = 0; // global

void handle_sig(int sig) {
    killzombies();
    exit(sig);
}

// your atexit()
void killzombies() {
    kill(0, SIGKILL);
    while (n_children > 0) {
        if (wait(NULL) != -1) {
            n_children--;
        }
    }
}
person Dan Albert    schedule 14.09.2012