ProgramingTip

For 루프에서 포크 ()

bestdevel 2020. 11. 25. 08:14
반응형

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이 실행을 실행했습니다 . 그러나 나는 그것을 이해하지 않습니다. 그래서 다음 다이어그램을 그렸습니다.

여기에 이미지 설명 입력

주석을 반영하도록 업데이트 된 다이어그램 :)

관찰 :

  1. 상위 프로세스 (기본)는 루프를 3 번 ​​반복해야합니다. 그런 다음 printf가 호출됩니다.
  2. 루프의 각 반복에서 fork ()가 호출됩니다.
  3. 각 fork () 호출 후 i가 증가하는 모든 시작이 증가합니다.
  4. 각 for 루프 끝에 "hi"가 인쇄됩니다.

내 질문은 다음과 같습니다.

  • 내 다이어그램이 정확합니까?
  • 출력에의 인스턴스가 i=0있는 이유는 무엇 입니까?
  • ifork () 이후에 각 자식에게 어떤 값 이 전달됩니까? 동일한 값 i이 이월되면 "포킹"이 언제 중지됩니까?
  • 2^n - 1갈래로 갈라진 아이들의 수를 세는 것이 항상 그런 경우 입니까? 자, 여기는 아이들 n=3을 의미합니다 2^3 - 1 = 8 - 1 = 7. 어느 것이 맞습니까?

for루프 에서 시작하여 이해하는 방법은 다음과 같습니다 .

  1. 루프는 부모에서 시작됩니다. i == 0

  2. 부모 fork()s, 자식 생성 1.

  3. 이제 두 개의 프로세스가 있습니다. 둘 다 인쇄 i=0합니다.

  4. 이제 두 프로세스에서 루프가 다시 시작됩니다 i == 1.

  5. 부모와 자식 1 fork(), 자식 2와 3을 만듭니다.

  6. 이제 4 개의 프로세스가 있습니다. 네 가지 모두 인쇄 i=1합니다.

  7. 루프는 이제 4 개 프로세스 모두에서 다시 시작됩니다 i == 2.

  8. 부모와 자식 1 ~ 3 모두 fork(), 4 ~ 7 자식을 만듭니다.

  9. 이제 8 개의 프로세스가 있습니다. 모두 여덟 인쇄 i=2.

  10. 루프는 8 개 프로세스 모두에서 다시 시작됩니다 i == 3.

  11. 루프 i < 3는 더 이상 사실이 아니므 로 8 개 프로세스 모두에서 종료됩니다 .

  12. 8 개의 프로세스가 모두 인쇄 hi됩니다.

  13. 8 개의 프로세스가 모두 종료됩니다.

따라서 0두 번 1인쇄되고, 네 번 2인쇄되고, hi8 번 인쇄 되고, 8 번 인쇄됩니다.


  1. 네, 맞습니다. (아래 참조)
  2. 아니요, 루프가 작동 하는 방식이기 때문에를 호출 한 후에i++ 실행 됩니다.forkfor
  3. 모든 것이 성공적으로 진행되면 그렇습니다. 그러나 fork실패 할 수 있음을 기억하십시오 .

두 번째에 대한 약간의 설명 :

for (i = 0;i < 3; i++)
{
   fork();
}

와 비슷하다:

i = 0;
while (i < 3)
{
    fork();
    i++;
}

따라서 i분기 된 프로세스 (상위 및 하위 모두)에서 증가 전의 값이 있습니다. 그러나 증분은 즉시 실행 fork()되므로 제 생각에는 다이어그램이 올바른 것으로 취급 될 수 있습니다.


질문에 하나씩 답변하려면 :

내 다이어그램이 정확합니까?

예, 본질적으로. 또한 매우 멋진 다이어그램입니다.

즉, i=0etc. 레이블을 전체 루프 반복을 참조하는 것으로 해석하면 맞습니다 . 그러나 다이어그램에 표시 되지 않는 것은 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

반응형