#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()
.