2017-02-10 3 views
1

Я не понимаю, в чем разница между fork() & fork() и fork() && fork(). Я также получаю разные результаты для них обоих.Путаница относительно системного вызова fork() в C

fork() & fork(); 
printf("hi\n"); 

Output : hi 
hi 
hi 
hi 

fork() && fork(); 
printf("hi\n"); 

Output: hi 
hi 
hi 

Может кто-нибудь, пожалуйста, объясните, что происходит здесь. Это проблема компилятора? (Я использую gcc на ubuntu14)

+0

Способ, которым я хотел бы подойти к этой проблеме, - сначала узнать разницу между '&' и '&&', найдя ресурс о операторах C. Затем я узнал, что делает «fork», читая для него спецификацию POSIX или справочную страницу Linux. –

ответ

3

Один выполняет логический тест, другой выполняет поразрядное и результат.

fork() && fork() 

Это будет вилкой. В родительском элементе он будет вилка снова, потому что первый fork вычисляет ненулевое значение (pid), а в дочернем случае это не будет.

fork() & fork() 

Оба родителя и дети будут раскошелиться, потому что это выполняет побитовое и возвращаемого значения вилки (либо PID или ноль).

1

в fork() && fork() первой вилки возврата 0. Это означает, ложные и поэтому оценка остальной части пункта && оставлена ​​(это будет ложным, независимо от значения остальной части пункта)

& версия всегда оценивает (Выполняет) с обеих сторон

Его, как

if (x != null && x->foo == 42) 
    printf("42"); 

вторая часть (Foo == 42) не затрагивается, если первая часть (х! = NULL) ложно

0

Это связано с тем, что оператор && имеет short-circuit evaluation. В принципе, для любого выражения x && y, сначала оценивается x. Если результат равен false, y не оценивается вообще, и все выражение оценивается в false. В противном случае результатом будет оценка y, при необходимости, в виде булева. Так, например, false && printf("Is this evaluated?\n") ничего не печатает.

Это означает, что fork() && fork() сначала оценивает первый fork() и оценивает второе, если и только если первый результат приводит к ненулевому результату. В частном случае функции fork() это происходит только в родительском процессе, так как ребенок получает статус возврата 0. Таким образом, исходные родительские вилки дважды, но у детей этого нет. В результате будет создано только три процесса.

Оператор &, с другой стороны, не имеет оценки короткого замыкания, поскольку он не является логическим - И, но побитовым - И. Поскольку & не относится к логическим значениям, а о битах (в отличие от &&), оба аргумента всегда оцениваются. Это означает, что в случае fork() & fork() родитель будет вилка дважды, а первый ребенок снова разветвится, что приведет к четырем различным процессам.

Кстати, вы должны изучать язык C, а не прыгать прямо на fork(). Если вы используете инструмент, вы не понимаете, что такие проблемы возвратятся вам часто.