Убийство раздвоенного ребенка убивает родителя? - PullRequest
12 голосов
/ 22 ноября 2011

У меня странное поведение, когда у меня есть основная программа и разветвленный ребенок. Они передаются следующим образом (номера являются дескрипторами файлов):

 ___parent___
|            |                     ____child_____
| 0 stdin    |                    |              |
| 1 pipe1[1]----------.           |  1 stdout    |
| 2 pipe2[1]----------.\          |  2 stderr    |
|____________|         \`----------> 3 pipe1[0]  | 
                        `----------> 5 pipe2[0]  |
                                  |______________|

Таким образом, родительский элемент получает данные от stdin , но перенаправляет stdout и stderr на два канала. Ребенок закрыл свой stdin и вместо этого использует прочитанные концы каналов.

Тогда у меня есть функция, чтобы просто убить ребенка:

void killChild(){
  printf("Killing %d\n", (int)childID);
  fflush(stdout);
  kill(childID, SIGKILL);
  waitpid(childID, NULL, 0);   // getting rid of the zombie
}

Ребенок был успешно убит, но проблема в том, что сам родитель тоже был убит . Я проверил PID ребенка, и это правильно.

Так почему же родитель умирает?

Ответы [ 2 ]

13 голосов
/ 22 ноября 2011

Любая попытка родителя записать его в fd 1 или fd 2 после выхода из дочернего процесса приведет к тому, что ядро ​​отправит SIGPIPE родителю.Поведение по умолчанию для SIGPIPE - завершение процесса.Это, вероятно, то, что происходит.

2 голосов
/ 22 ноября 2011

Вам нужно обрабатывать сигналы SIGPIPE и SIGCHLD - возможно, просто игнорировать их - и у вас все будет хорошо.

...