Fork () в качестве аргумента

Обычно, когда мне нужно выполнить форк в 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 */ }

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
667
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

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

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

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

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

Ответ принят как подходящий

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

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

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