Это называется логическим оператором И. Это позволит оценить логический результат ANDing двух операндов. Свойство этого оператора:
Сначала оценивается левый операнд, если он TRUE (не ноль), то правый операнд оценивается. Если это также правда, тогда все выражение верно или иначе ложно. С другой стороны, если левый операнд равен FALSE, то правый операнд равен , а не . Это может быть сделано, потому что, поскольку один из операндов является ложным, каким бы ни был другой операнд, выражение становится ложным. Это известно как короткое замыкание
В вашем коде, если левая рука, если ret
- истина, то оценивается только правая часть, которая в итоге вызывает системный вызов fork ()
. Возвращаемым значением вызова является AND с текущим значением ret
и переназначается на ret
.
В основном это работает как
if (ret == TRUE)
{
retval = fork ();
ret = ret && retval;
}
Читать это:
В случае успеха PID дочернего процесса возвращается в родительском, а 0 - в дочернем. В случае ошибки -1 возвращается в родительский процесс, дочерний процесс не создается и значение errno устанавливается соответствующим образом.
Рассмотрим ветвление дерева ниже. Каждый "узел" дерева показывает последовательность выполненного оператора в каждом отдельном операторе. Одна работа в одной строке.
(p1)
+--+ret = fork ();
| printf 1 shows pid
| && allows fork (), ret = 1 = pid1 && pid2
| printf 2 shows 1 +
| `if' not entered |
| show hello |
| | (p3)
| +--+ ret = 0 = ret && fork () (this is 0 here)
+-----+ printf 2 shows 0
| `if' is entered
| fork ()
| show hello
| +
| |
+ |
(p2) |
level 1 +-------+
print 0 in 1st printf |
&& DOES NOT allow fork () (p5)
print 0 in 2st printf show hello
`if' entered
fork () +-----------+
show hello |
|
+
(p4)
show hello
Вот что происходит в каждом процессе.
p1
выполняет fork ()
один раз и имеет pid (ненулевой) в ret.
печатает пид
короткое замыкание позволяет выполнить fork (). Так как это родитель, он возвращает другой pid, который добавляется к предыдущему дочернему pid, который оценивается как 1. Следовательно, ret
теперь содержит 1, который печатается во втором printf. ret
равно 1, if
не выполняется. Привет напечатано.
p2
Дочерний элемент p1, поэтому ret имеет 0. печатает 0 в первом printf. Короткое замыкание не позволяет fork ()
звонить. if
тело вводится, и вызывается fork ()
, что составляет (p4). Теперь (p2) приступает к печати Hello.
p3
Дочерний элемент p1, поэтому fork ()
return равно 0, что равно AND с ret и делает его 0 после присваивания. Это порождается после первого printf, поэтому только второй printf показывает 0.
if
введено, fork ()
выполнено, что составляет (p5). Теперь p4 приступает к печати Hello.
p4
начинается с if
body, выходит и печатает Hello
p5
начинается с if
body, выходит и печатает Hello
Выше я попытался выразить дерево порождения процесса, и последовательность работ в каждом процессе выражена в каждой строке "узла" процесса на дереве. Ребра обозначают икру, а ребра начинаются с соответствующей вилки.