Вопрос
Обычно, когда мне нужно раскошелиться на 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 и т.д.