이 프로그램은 왜 "forked!"를 인쇄합니까? 4 회?
이 프로그램은 왜 "forked!"를 인쇄합니까? 4 회?
#include <stdio.h>
#include <unistd.h>
int main(void) {
fork() && (fork() || fork());
printf("forked!\n");
return 0;
}
첫 번째 fork()
는 호출 프로세스에서 0이 아닌 값 (p0이라고 함)을 반환하고 자식에서는 0 (p1이라고 함)을 반환합니다.
p1에서는 단락 &&
이 발생하고 프로세스가 호출 printf
되고 종료됩니다. p0에서 프로세스는 표현식의 나머지를 평가해야합니다. 그런 다음 fork()
다시 호출 하여 새 자식 프로세스 (p2)를 만듭니다.
p0 fork()
에서 0이 아닌 값을 반환하고 단락 ||
이 발생하므로 프로세스가 호출 printf
되고 종료됩니다.
p2에서는 fork()
0을 반환하므로 나머지는 || 평가되어야합니다 fork()
. 그 결과 p2에 대한 자식이 생성됩니다 (p3라고 함).
그런 다음 P2가 실행 printf
되고 종료됩니다.
그런 다음 P3가 실행 printf
되고 종료됩니다.
printf
그런 다음 4 초가 실행됩니다.
하나는 main()
모든 fork()
.
세 가지 forks()
가 모두 실행됩니다. 심판을 살펴보고 싶을 수도 있습니다 .
반환 가치
성공적으로 완료되면 fork ()는 자식 프로세스에 0을 반환하고 자식 프로세스의 프로세스 ID를 부모 프로세스에 반환합니다 . 두 프로세스 모두 fork () 함수에서 계속 실행됩니다. 그렇지 않으면 -1이 부모 프로세스로 반환되고 자식 프로세스가 생성되지 않으며 errno가 오류를 표시하도록 설정됩니다.
여기에 설명 된대로 프로세스 ID는 0이 될 수 없습니다 .
그래서 실제로 어떻게됩니까?
우리는 :
fork() && (fork() || fork());
따라서 첫 번째 fork()
는 0이 아닌 프로세스 ID를 부모에게 반환하고 자식 프로세스에는 0을 반환합니다. 즉, 논리 표현식의 첫 번째 포크는 부모 프로세스에서 true로 평가되고 자식 프로세스에서는 false로 평가되며 단락 평가 로 인해 나머지 두 fork()
s를 호출하지 않습니다 .
이제 우리는 적어도 두 장의 인쇄물을 얻을 것임을 압니다 (하나는 main에서 하나는 1st에서 하나 fork()
).
이제 fork()
부모 프로세스 의 두 번째 가 실행되고 실행되고 부모 프로세스에 0이 아닌 값을 반환하고 자식 프로세스에 0을 반환합니다.
따라서 이제 부모는 마지막 fork()
(단락으로 인해) 실행을 계속하지 않고 자식 프로세스는 첫 번째 피연산자 ||
가 0 이므로 마지막 포크를 실행합니다 .
즉, 두 장 더 인쇄 할 수 있습니다.
그 결과 총 4 장의 인쇄물이 나옵니다.
단락
여기서 단락은 기본적으로 &&의 첫 번째 피연산자가 0이면 다른 피연산자가 평가되지 않음을 의미합니다. 같은 논리에서 피연산자가 || 1이면 나머지 피연산자는 평가가 필요하지 않습니다. 나머지 피연산자는 논리 표현식의 결과를 변경할 수 없기 때문에 실행될 필요가 없으므로 시간을 절약 할 수 있습니다.
아래 예를 참조하십시오.
방법
부모 프로세스는 자손 프로세스를 생성하고 다른 프로세스 등을 생성한다는 것을 기억하십시오. 이것은 프로세스의 계층 구조 (또는 트리라고 말할 수 있음)로 이어집니다.
이 점을 염두에 데, 그것의 가치는 이것 좀 복용 비슷한 문제 뿐만 아니라, 이 대답을.
설명 이미지
나는 또한 도움이 될 수있는이 그림을 만들었습니다. fork()
반환 된 pid 는 모든 호출에 대해 3, 4 및 5 라고 가정했습니다 .
일부 fork()
s는 그 위에 빨간색 X가 있습니다. 이는 논리 표현식의 평가가 단락되어 실행되지 않음을 의미합니다.
fork()
연산자의 첫 번째 피연산자 &&
가 0 이므로 맨 위에 있는 s는 실행되지 않습니다 . 따라서 전체 표현식이 0이되므로의 나머지 피연산자를 실행하는 데 본질이 없습니다 &&
.
fork()
그것의 두 번째 피연산자 이후 하단에이 실행되지 않습니다 ||
첫 번째 피연산자가 이미 true로 평가되는이 아닌 제로 숫자 식의 따라서 결과, 두 번째 피연산자가 무엇인지에 상관없이입니다.
그리고 다음 그림 에서 이전 그림을 기반으로 한 프로세스의 계층 구조를 볼 수 있습니다 .
단락의 예
#include <stdio.h>
int main(void) {
if(printf("A printf() results in logic true\n"))
;//empty body
if(0 && printf("Short circuiting will not let me execute\n"))
;
else if(0 || printf("I have to be executed\n"))
;
else if(1 || printf("No need for me to get executed\n"))
;
else
printf("The answer wasn't nonsense after all!\n");
return 0;
}
산출:
A printf() results in logic true
I have to be executed
모든 반대 투표자에게 이것은 병합되었지만 다른 질문에서 나온 것입니다. 그래서 비난. 감사합니다.
You can decompose the problem to three lines, the first and last lines both simply double the number of processes.
fork() && fork() || fork();
The operators are short-circuiting, so this is what you get:
fork()
/ \
0/ \>0
|| fork() && fork()
/\ / \
/ \ 0/ \>0
* * || fork() *
/ \
* *
So this is altogether 4 * 5 = 20 processes each printing one line.
Note: If for some reason fork() fails (for example, you have some limit on the number of processes), it returns -1 and then you can get different results.
Executing fork() && (fork() || fork())
, what happens
Each fork
gives 2 processes with respectively values pid (parent) and 0 (child)
First fork :
- parent return value is pid not null => executes the
&& (fork() || fork())
- second fork parent value is pid not null stops executing the
||
part => printforked
- second fork child value = 0 => executes the
|| fork()
- third fork parent prints
forked
- third fork child prints
forked
- third fork parent prints
- second fork parent value is pid not null stops executing the
- 자식 반환 값은 0입니다 && 부분 => 인쇄 실행 중지
forked
합계 : 4 forked
이미 제출 된 모든 답변이 마음에 듭니다. 아마도 printf 문에 몇 가지 변수를 더 추가하면 무슨 일이 일어나고 있는지 더 쉽게 볼 수 있습니다.
#include<stdio.h>
#include<unistd.h>
int main(){
long child = fork() && (fork() || fork());
printf("forked! PID=%ld Child=%ld\n", getpid(), child);
return 0;
}
내 컴퓨터에서 다음과 같은 출력이 생성되었습니다.
forked! PID=3694 Child = 0
forked! PID=3696 Child = 0
forked! PID=3693 Child = 1
forked! PID=3695 Child = 1
이 코드 :
fork();
fork() && fork() || fork();
fork();
자체적으로 20 개의 프로세스를 가져오고 Printf가 20 번 진행합니다.
그리고
fork() && fork() || fork();
printf는 총 5 번 진행됩니다.
참고 URL : https://stackoverflow.com/questions/26716255/why-does-this-program-print-forked-4-times
'Nice programing' 카테고리의 다른 글
디렉토리에 대한“401 Unauthorized” (0) | 2020.10.17 |
---|---|
코드 서명 오류 : 프로비저닝 프로필을 찾을 수 없습니다. (0) | 2020.10.17 |
Python의 일반적인 함정 (0) | 2020.10.17 |
하위 쿼리를 조건으로 사용하는 MySQL DELETE FROM (0) | 2020.10.17 |
pip 설치 /usr/local/opt/python/bin/python2.7 : 잘못된 인터프리터 : 해당 파일 또는 디렉토리 없음 (0) | 2020.10.17 |