LINUX.ORG.RU

Вопрос к знатокам по waitpid и SIGCHLD.


0

0

Ситуация такая: процесс устанавливает обработик SIGCHLD и запускает
процессы прсредством fork-exec. В этом обработчике делается wait() для того,
чтобы узнать pid завершившегося только что процесса. Запускается один
процесс, все срабатывает как нужно - pid определяется правильно. Но
затем вдруг происходит еще один вход в обработчик SIGCHLD, хотя
запроса на создание нового процесса не приходило, и wait()
повисает. Как такое может быть? Программа многотредовая, но я пробовал
выставлять флаг __WNOTHREAD в вызове waitpid(-1, &stat, FLAGS) -
результат тот же. Кроме того, я пробовал инсталлировать обработчик с
флажком SA_NOCLDSTOP - та же история. Больше я ничего придумать не
смог. В принципе, такая ситуация может случиться, если еще кто-то скажет
wait(), но никто больше в моей программе этого не делает.

В чем же может быть дело?

Заранее огромное спасибо!

anonymous

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

void sig_t_child(int signal){
    pid_t pid;
    int status;
    while((pid = waitpid(-1,&status,WNOHANG)) > 0){   
    }
}

/*инициализация обработчика*/
struct sigaction sig_action;
bzero(&sig_action, sizeof(struct sigaction));
sig_action.sa_handler = &sig_t_child;
sig_action.sa_flags = SA_NOCLDSTOP | SA_RESTART;
sigaction (SIGCHLD, &sig_action, NULL);

Dead ★★★★
()
Ответ на: комментарий от Dead

Дык :) Конечно, я себе сделал этот воркароунд. Вопрос в том, почему происходит то, что я описал...

anonymous
()
Ответ на: комментарий от anonymous

Ведь такая ситуация может означать какие-то неполадки внутри программы, разве нет?

anonymous
()

если у вас обработчик типа:

reaper()
{
        while ((pid = waitpid(...)) > 0)
                do_something(pid);
}

то вы действительно можете получить SIGCHLD,
а wait() завершенных процессов не обнаружит.

потому что. пусть завершился child. входим
в обработчик, получаем первый pid. завершается
еще один child, процессу посылается сигнал, но
он блокирован, т.к. мы в обработчике. цикл
вытаскивает еще pid, выходим из обработчика,
и сразу снова туда же попадаем, т.к. у процесса
pending SIGCHLD. но теперь wait4() никого не
найдет.

idle ★★★★★
()
Ответ на: комментарий от Murr

> А если fork->clone (...SIGRTMIN...)?

так тогда и будет SIGRTMIN, а не SIGCHLD.
потом, ничего не поменяется, сигнал все
равно блокирован в обработчике, если не
SA_NODEFER. другое дело, что при SIGRTMIN
теоретически можно делать wait() без цикла.

idle ★★★★★
()
Ответ на: комментарий от idle

idle: Ага ;) Просто к слову пришлось о пропущенных сигналах. ;)

Murr ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.