Вопрос

Обычно, когда мне нужно раскошелиться на C, я делаю что-то вроде этого:

pid_t p = fork();
if(p == 0) { /* do child stuff */ }
else { /* do parent stuff and pray there wasn't an error */ }

Мне пришло в голову, что я мог бы отказаться от дополнительной переменной и использовать:

if(fork() == 0) { /* child */ }
else { /* parent/pray */ }

Помимо неправильной обработки ошибок, (почему) это работает / не работает?

Это было полезно?

Решение

То, что вы предлагаете, безусловно, сработает.Однако обработка ошибок не является необязательной в любом хорошо работающем приложении.Следующий шаблон реализации аналогично лаконичен и также обрабатывает ошибки.Кроме того, он сохраняет возвращаемое значение fork() в переменной pid на случай, если вы захотите использовать его позже в родительском файле, скажем, для ожидания дочернего элемента.

switch (pid = fork()) {
case -1:       /* Failure */
  /* ... */
case 0:        /* Child */
  /* ... */
default:       /* Parent */
  /* ... */
}

Другие советы

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

Также возвращается значение -1, если при разветвлении произошла ошибка, которую вы не тестируете ни в том, ни в другом случае, что обычно является ошибкой.

Вы должны сделать это вместо этого.Я никогда не знал, чтобы это не сработало.Именно так это делается в книгах Стивенса.

int p;
if((p = fork()) == 0) { /* child */ }
else { /* parent/pray */ }

Вы можете сделать это на C, и это сработает, потому что родительский и дочерний элементы будут получать разные возвращаемые значения из fork - и это оценивается в первую очередь.Единственные проблемы - это обработка ошибок, как вы упомянули.Кроме того, у вас не будет никакого другого способа восстановить дочерний PID на случай, если вы захотите оперировать с ним, например, с помощью waitpid и т.д.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top