Проблемы C++ fork() и execv()
Вопрос
Я новичок в C++ и работаю над простой программой в Linux, которая должна вызывать другую программу в том же каталоге и получать выходные данные вызванной программы, не показывая выходные данные вызванной программы на консоли.Это фрагмент кода, над которым я работаю:
pid_t pid;
cout<<"General sentance:"<<endl<<sentence<<endl;
cout<<"==============================="<<endl;
//int i=system("./Satzoo");
if(pid=fork()<0)
cout<<"Process could not be created..."<<endl;
else
{
cout<<pid<<endl;
execv("./Satzoo",NULL);
}
cout<<"General sentance:"<<endl<<sentence<<endl;
cout<<"==============================="<<endl;
Одна из проблем, с которой я столкнулся, заключается в том, что я могу напечатать первые две строки на консоли, но не могу напечатать последние две строки.Я думаю, что программа перестает работать, когда я запускаю программу Satzoo.Другое дело, что этот код дважды вызывает программу Satzoo, я не знаю почему?Я вижу результат на экране дважды.С другой стороны, если я использую system() вместо execv(), Satzoo сработает только один раз.
Я не понял, как читать вывод Satzoo в своей программе.
Любая помощь приветствуется.
Спасибо
Решение
Вы не отличаетесь между ребенком и родительским процессом после вызова fork()
. Анкет Итак, и ребенок, и родитель бегают execv()
и, таким образом, их соответствующие изображения процесса заменяются.
Вы хотите что -то большее:
pid_t pid;
printf("before fork\n");
if((pid = fork()) < 0)
{
printf("an error occurred while forking\n");
}
else if(pid == 0)
{
/* this is the child */
printf("the child's pid is: %d\n", getpid());
execv("./Satzoo",NULL);
printf("if this line is printed then execv failed\n");
}
else
{
/* this is the parent */
printf("parent continues execution\n");
}
Другие советы
А fork()
функция клонирует текущий процесс и возвращает другой ценности в каждом процессе.В «родительском» процессе он возвращает pid дочернего процесса.В дочернем процессе он возвращает ноль.Поэтому вы обычно вызываете его, используя такую модель:
if (fork() > 0) {
cout << "in parent" << endl;
} else {
cout << "in child" << endl;
exit(0);
}
Я пропустил обработку ошибок выше.
В вашем примере оба приведенных выше пути кода (родительский и дочерний) попадают в else
пункт вашего звонка fork()
, в результате чего они оба execv("./Satzoo")
.Вот почему ваша программа выполняется дважды и почему вы никогда не достигаете дальнейших утверждений.
Вместо использования fork()
и делать все вручную (правильное управление выполнением процессов — это изрядный объем работы), вас может заинтересовать использование popen()
вместо этого функция:
FILE *in = popen("./Satzoo", "r");
// use "in" like a normal stdio FILE to read the output of Satzoo
pclose(in);
От fork()
Манстрация:
Возвращаемое значение
После успешного завершения Fork () возвращает 0 в процесс ребенка и должен вернуть идентификатор процесса процесса дочернего процесса в родительский процесс. Оба процесса должны продолжать выполнять функцию fork (). В противном случае -1 должен быть возвращен в родительский процесс, детский процесс не должен быть создан, и Errno должен быть установлен для указания ошибки.
Вы проверяете, чтобы убедиться, что это удастся, но не pid
Указывает, что мы находимся в ребенке или родителе. Таким образом, и ребенок, и родитель делают одно и то же дважды, что означает, что ваша программа выполняется дважды, а окончательный текст никогда не печатается. Вам нужно проверить возвращаемое значение fork()
больше, чем один раз.
Exec - Семейство функций exec () заменяет текущее изображение процесса новым изображением процесса.
Система - блокирует выполнение команды. Выполнение вызовой программы продолжается после возврата команды системы
Есть три теста на обратную стоимость, которые вы хотите с вилкой
- 0: ты ребенок
- -1: ошибка
- Другое: ты родитель
Вы управляли другой программой от ребенка и родителя ...