For 루프에서 포크 ()
나는 행동 을 이해하려고 노력해 왔습니다 . 이번에는 . 다음 코드를 관찰하십시오.fork()
for-loop
#include <stdio.h>
void main()
{
int i;
for (i=0;i<3;i++)
{
fork();
// This printf statement is for debugging purposes
// getppid(): gets the parent process-id
// getpid(): get child process-id
printf("[%d] [%d] i=%d\n", getppid(), getpid(), i);
}
printf("[%d] [%d] hi\n", getppid(), getpid());
}
다음은 출력입니다.
[6909][6936] i=0
[6909][6936] i=1
[6936][6938] i=1
[6909][6936] i=2
[6909][6936] hi
[6936][6938] i=2
[6936][6938] hi
[6938][6940] i=2
[6938][6940] hi
[1][6937] i=0
[1][6939] i=2
[1][6939] hi
[1][6937] i=1
[6937][6941] i=1
[1][6937] i=2
[1][6937] hi
[6937][6941] i=2
[6937][6941] hi
[6937][6942] i=2
[6937][6942] hi
[1][6943] i=2
[1][6943] hi
나는 매우 매우 진정 인 사람이기 때문에 내가 사물을 진정으로 이해하는 유일한 방법은 다이어그램을 작성하는 것입니다. 제 강사는 8 개의 안녕 진술 이있을 것이라고 말했습니다 . 코드를 작성하고 실제로 8 개의 hi 문 이 실행을 실행했습니다 . 그러나 나는 그것을 이해하지 않습니다. 그래서 다음 다이어그램을 그렸습니다.
주석을 반영하도록 업데이트 된 다이어그램 :)
관찰 :
- 상위 프로세스 (기본)는 루프를 3 번 반복해야합니다. 그런 다음 printf가 호출됩니다.
- 루프의 각 반복에서 fork ()가 호출됩니다.
- 각 fork () 호출 후 i가 증가하는 모든 시작이 증가합니다.
- 각 for 루프 끝에 "hi"가 인쇄됩니다.
내 질문은 다음과 같습니다.
- 내 다이어그램이 정확합니까?
- 출력에의 두 인스턴스가
i=0
있는 이유는 무엇 입니까? i
fork () 이후에 각 자식에게 어떤 값 이 전달됩니까? 동일한 값i
이 이월되면 "포킹"이 언제 중지됩니까?2^n - 1
갈래로 갈라진 아이들의 수를 세는 것이 항상 그런 경우 입니까? 자, 여기는 아이들n=3
을 의미합니다2^3 - 1 = 8 - 1 = 7
. 어느 것이 맞습니까?
for
루프 에서 시작하여 이해하는 방법은 다음과 같습니다 .
루프는 부모에서 시작됩니다.
i == 0
부모
fork()
s, 자식 생성 1.이제 두 개의 프로세스가 있습니다. 둘 다 인쇄
i=0
합니다.이제 두 프로세스에서 루프가 다시 시작됩니다
i == 1
.부모와 자식 1
fork()
, 자식 2와 3을 만듭니다.이제 4 개의 프로세스가 있습니다. 네 가지 모두 인쇄
i=1
합니다.루프는 이제 4 개 프로세스 모두에서 다시 시작됩니다
i == 2
.부모와 자식 1 ~ 3 모두
fork()
, 4 ~ 7 자식을 만듭니다.이제 8 개의 프로세스가 있습니다. 모두 여덟 인쇄
i=2
.루프는 8 개 프로세스 모두에서 다시 시작됩니다
i == 3
.루프
i < 3
는 더 이상 사실이 아니므 로 8 개 프로세스 모두에서 종료됩니다 .8 개의 프로세스가 모두 인쇄
hi
됩니다.8 개의 프로세스가 모두 종료됩니다.
따라서 0
두 번 1
인쇄되고, 네 번 2
인쇄되고, hi
8 번 인쇄 되고, 8 번 인쇄됩니다.
- 네, 맞습니다. (아래 참조)
- 아니요, 루프가 작동 하는 방식이기 때문에를 호출 한 후에
i++
실행 됩니다.fork
for
- 모든 것이 성공적으로 진행되면 그렇습니다. 그러나
fork
실패 할 수 있음을 기억하십시오 .
두 번째에 대한 약간의 설명 :
for (i = 0;i < 3; i++)
{
fork();
}
와 비슷하다:
i = 0;
while (i < 3)
{
fork();
i++;
}
따라서 i
분기 된 프로세스 (상위 및 하위 모두)에서 증가 전의 값이 있습니다. 그러나 증분은 즉시 실행 fork()
되므로 제 생각에는 다이어그램이 올바른 것으로 취급 될 수 있습니다.
질문에 하나씩 답변하려면 :
내 다이어그램이 정확합니까?
예, 본질적으로. 또한 매우 멋진 다이어그램입니다.
즉, i=0
etc. 레이블을 전체 루프 반복을 참조하는 것으로 해석하면 맞습니다 . 그러나 다이어그램에 표시 되지 않는 것은 each fork()
이후에 fork()
호출 후 현재 루프 반복의 일부가 분기 된 자식 프로세스에 의해 실행된다는 것입니다.
i=0
출력에의 두 인스턴스가 있는 이유는 무엇 입니까?
왜냐하면 printf()
이후 fork()
에이므로 부모 프로세스와 방금 분기 된 자식 프로세스 모두에서 실행됩니다. printf()
이전 에을 이동하면 fork()
부모에 의해서만 실행됩니다 (아직 자식 프로세스가 존재하지 않기 때문에).
i
이후 각 어린이에게 이월되는 가치는 무엇입니까fork()
? 동일한 값i
이 이월되면 "포킹"이 언제 중지됩니까?
의 값은 i
에 의해 변경되지 않으므로 fork()
자식 프로세스는 부모와 동일한 값을 봅니다.
기억해야 할 점 fork()
은 한 번 호출되었지만 부모 프로세스에서 한 번, 새로 복제 된 자식 프로세스에서 한 번 두 번 반환된다는 것입니다.
더 간단한 예제를 위해 다음 코드를 고려하십시오.
printf("This will be printed once.\n");
fork();
printf("This will be printed twice.\n");
fork();
printf("This will be printed four times.\n");
fork();
printf("This will be printed eight times.\n");
에 의해 생성 된 자식 프로세스 fork()
는 부모의 (거의) 정확한 복제본이므로 자체 관점에서 부모 프로세스의 모든 상태 (모든 변수 값, 호출 스택 및 모든 변수 포함)를 상속하는 부모임을 "기억"합니다. 실행중인 명령). 유일한 즉각적인 차이점 (에서 반환 된 프로세스 ID와 같은 시스템 메타 데이터 제외 getpid()
)은의 반환 값입니다 fork()
.이 값은 자식 프로세스에서는 0이되고 부모에서는 0이 아닙니다 (실제로 자식 프로세스의 ID).
2^n - 1
갈래로 갈라진 아이들의 수를 세는 것이 항상 그런 경우 입니까? 자, 여기는 아이들n=3
을 의미합니다2^3 - 1 = 8 - 1 = 7
. 어느 것이 맞습니까?
실행하는 모든를 프로세스는 fork()
두 개의 프로세스로 바뀝니다 (오류보기 조건에서 비정상적인 fork()
실패 할 수 있는 경우 제외 ). 부모와 동일한 코드를 계속 실행하는 경우 (즉,의 반환 값 fork()
또는 자체 프로세스 ID를 확인하지 않고 이를 기반으로 다른 코드 경로로 분기) 각 후속 포크는 프로세스 수를 두 배로 늘립니다. 예, 세 개의 포크 나중에는 총 2³ = 8 개의 프로세스가 처리됩니다.
참고 URL : https://stackoverflow.com/questions/26793402/visually-what-happens-to-fork-in-a-for-loop
'ProgramingTip' 카테고리의 다른 글
JUnit 테스트 케이스에서 자원 파일을 제거 수 없음 (0) | 2020.11.25 |
---|---|
OwinStartup시 DI 컨테이너 사용 방법 (0) | 2020.11.25 |
Azure DevOps, YAML 릴리스 파이프 라인? (0) | 2020.11.25 |
둘 이상의 항목이 이미 발견 된 경우에도 Enumerable.Single ()이 모든 요소를 반복하는 이유는 무엇입니까? (0) | 2020.11.25 |
JWT를 localStorage 또는 쿠키에 저장해야합니까? (0) | 2020.11.25 |