linux fork — execl, исполняемый процесс становится зомби

Я пытаюсь запустить командную строку мерцания от дочернего процесса.
Например, вот так:

int hangup() {
write_on_display("line3", "            ");
write_on_display("hide_icon", "DIALTONE");
write_on_display("hide_icon", "BACKLIGHT");

int pid = fork();
if (pid == 0) {
int res = execl("/usr/bin/twinkle", " ", "--immediate", "--cmd",
"answerbye", (char *) NULL);
_exit(0);
} else {
perror("hangup");
return 0;
}
return 1;
}

но мерцание становится зомби

10020 pts/1    Z+     0:00 [twinkle] <defunct>
10040 pts/1    Z+     0:00 [twinkle] <defunct>
10053 pts/1    Z+     0:00 [twinkle] <defunct>
10064 pts/1    Z+     0:00 [twinkle] <defunct>
10097 pts/1    Z+     0:00 [twinkle] <defunct>
10108 pts/1    Z+     0:00 [twinkle] <defunct>
10130 pts/1    Z+     0:00 [twinkle] <defunct>

Я пытался установить
сигнал (SIGCHLD, SIG_IGN);
но без успеха.
На самом деле я думаю, что дочерний процесс умирает до того, как мерцание закончится.

Запуск мерцания из командной строки, как:

twinkle --immediate --call 100

не делает зомби — мерцание закрывается правильно.
Что мне там не хватает?

5

Решение

Родительский процесс должен вызвать waitpid() с идентификатором процесса ребенка. Со ссылочной страницы:

Все эти системные вызовы используются для ожидания изменений состояния дочернего процесса вызывающего процесса и получения информации о дочернем элементе, состояние которого изменилось. Изменением состояния считается: ребенок уволен; ребенок был остановлен сигналом; или ребенок был возобновлен по сигналу. В случае прерванного дочернего элемента выполнение ожидания позволяет системе высвободить ресурсы, связанные с дочерним элементом; если ожидание не выполняется, то прерванный ребенок остается в состоянии «зомби» (см. примечания ниже).

Например:

pid_t pid = fork();
if (0 == pid)
{
/* Child process. */
}
else
{
/* Parent process, wait for child to complete. */
int status;
waitpid(pid, &status, 0);
}
7

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

Да, но мне нужно, чтобы родитель и ребенок работали асинхронно.

На самом деле я нашел свою ошибку.
Так что, если у кого-то есть подобная проблема, с функцией обработчика сигнала, подобной этой:

void catch_child(int sig_num)
{
/* when we get here, we know there's a zombie child waiting */
int child_status;

wait(&child_status);

}

а также
сигнал (SIGCHLD, catch_child)

в функции main ()
все работает.

PP
Вот:
это очень хорошее объяснение.

4

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