Поддерживать разветвленный процесс в рабочем состоянии при аварийном завершении родительского / дочернего процесса (C )

#c #linux #process #exec #fork

#c #linux #процесс #exec #fork

Вопрос:

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

 // MAIN PROGRAM
pid = fork();
char *argv[] = { stuff.. };
if (pid == 0) {
    int rc = execv("command line program...", argv);
    }

// DO OTHER STUFF HERE. 

if (pid > 0) {
    waitpid(pid, 0, 0);
}
  

Есть ли какой-либо способ сохранить мою основную программу запущенной после аварийного завершения работы программы командной строки? Спасибо!

[ОБНОВЛЕНИЕ]: Да, основной процесс выполняет запись в файл, из которого выполняется чтение командной строки, но это обычный файл, а не канал. Я получаю ошибку segfault.

Мне чрезвычайно сложно воспроизвести ошибку, поскольку дочерний процесс не очень часто завершает работу. Но это происходит. Случайный сбой — известная ошибка в программе командной строки, поэтому я хочу сохранить свою основную программу в рабочем состоянии, даже если командная строка завершается.

Комментарии:

1. Основываясь на том, что вы опубликовали, я не понимаю, почему ваша основная программа умрет. Это происходит на самом деле или что-то, о чем вы беспокоитесь, происходит?

2. Если родитель и потомок каким-либо образом не взаимодействуют, маловероятно, что смерть дочернего процесса повлияет на родительский процесс. Является ли родительский процесс чтением / записью от / к дочернему процессу через канал? Возможно, вы получаете сигнал SIGPIPE? Или любой другой сигнал?

3. @Duck, но это действительно происходит… Итак, вы считаете, что это правильный способ сделать это?

4. @Luther Blissett: Спасибо за ваш ответ. Да, основной процесс выполняет запись в файл, из которого выполняется чтение командной строки, но это обычный файл, а не канал. Я получаю ошибку segfault.

5. @usfish: используете ли вы блокировку файлов?

Ответ №1:

В вашем реальном коде есть еще что-нибудь здесь:

 if (pid == 0) {
    int rc = execv("command line program...", argv);
    // possibly more child stuff
}
else {
    // parent stuff
}
  

Всегда полезно публиковать реальный код, задавая вопросы здесь.

Ответ №2:

  • Используйте vfork вместо fork , чтобы избежать ненужного клонирования процесса.
  • Убедитесь, что у вас не происходит сбой при SIGCHLD получении родительским процессом.
  • Используйте правильный оператор if-then-else, чтобы было ясно, какой код выполняется в родительском процессе и что происходит в дочернем процессе. Например, очень вероятно, что и дочерний процесс, и сам процесс выполнят код, в котором есть // DO OTHER STUFF HERE. комментарий на случай execv сбоя.
  • В конце концов, используйте gdb . Он сообщит вам, где происходит сбой.

Комментарии:

1. Я думаю, все же следует отметить, что vfork не существует во всех системах unixoid в соответствии с APUE (Стивенс, Раго), хотя он существует в Linux и некоторых других популярных системах unixoid.

2. POSIX должен posix_spawn() заменить vfork() .