프로세스를 생성하고자 할 때 fork 함수를 사용하면 됩니다.

fork 함수를 호출하는 프로세스는 부모 프로세스가 되고 새롭게 생성되는 프로세스는 자식 프로세스가 됩니다.

fork 함수에 의해 생성된 자식 프로세스는 부모 프로세스의 메모리를 그대로 복사하여 가지게 됩니다.

그리고 fork 함수 호출 이후 코드부터 각자의 메모리를 사용하여 실행됩니다


fork 함수를 사용하기 위해서는 unistd.h를 include하면 됩니다.

fork 함수는 unistd.h 파일에 system call로 정의되어 있습니다.

// unistd.h header file

pid_t fork(void); // 성공 시 : 부모 프로세스에서는 자식 프로세스의 PID값을 반환 받음

// 자식 프로세스에서는 0 값을 반환 받음

// 실패 시 : 음수 값(-1) 반환


간단한 예제 코드를 살펴 보겠습니다.

#include <stdio.h>
#include <unistd.h>

int main() {
    int x;
    x = 0;
    
    fork();
    
    x = 1;
    printf("PID : %ld,  x : %d\n",getpid(), x);
    
    return 0;
}


실행 결과는 다음과 같습니다.

fork 함수 코드 이후부터는 부모 프로세스와 자식 프로세스가 각자의 x = 1, printf() 코드를 실행하였습니다.

그렇기 때문에 PID 43889(부모 프로세스)에서 x 값은 1을 출력하였고 PID 43895(자식 프로세스)에서도 x 값은 1이라고 출력하였습니다.

PID : 43889,  x : 1

PID : 43895,  x : 1 


그림을 통하여 다시 한번 보도록 하겠습니다.

fork 함수가 실행 된 직후에는 자식 프로세스 부모 프로레스와 동일한 주소 공간의 복사본을 가지게 됩니다.

fork 함수 실행 이후 , 부모와 자식 프로세스는 동일한 코드 (x = 1, printf())를 각자 메모리상에서 실행하고 있습니다.


이번에는 fork 함수의 리턴값을 검사하여 부모와 자식 코드를 각각 분리하도록 하겠습니다.

fork 함수는 부모 프로세스에게는 자식프로세스의 PID를 반환하며 자식 프로세스에게는 0을 반환합니다.

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main() {
    
    pid_t pid;
    
    int x;
    x = 0;
    
    pid = fork();
    
    if(pid > 0) {  // 부모 코드
        x = 1;
        printf("부모 PID : %ld,  x : %d , pid : %d\n",(long)getpid(), x, pid);
    }
    else if(pid == 0){  // 자식 코드
        x = 2;
        printf("자식 PID : %ld,  x : %d\n",(long)getpid(), x);
    }
    else {  // fork 실패
        printf("fork Fail! \n");
        return -1;
    }
    
    return 0;

}


실행 결과는 다음과 같습니다. 

pid 반환값을 검사하여 부모 프로세스와 자식 프로세스에서 실행될 코드를 별도로 작성할 수 있는것을 확인 하였습니다.

부모 PID : 46834,  x : 1 , pid : 46838

자식 PID : 46838,  x : 2 


fork 함수가 실행 된 직후에는 자식 프로세스 부모 프로레스와 동일한 주소 공간의 복사본을 가지게 됩니다.

하지만 fork 함수 이후의 코드가 pid값을 기준으로 분리되어 있습니다.

따라서 각 프로세스의 메모리 공간의 x값은 서로 달라지게 됩니다. 


지금까지 fork 함수 사용에 대해서 살펴 보았습니다.

  1. E.asiest 2019.09.04 22:56 신고

    안녕하세요!
    블로그 설명 덕분에 이해가 잘 갑니다! 감사합니다~
    실습을 해봤는데요!(vmware kali)
    왜 저는 OXOX 이렇게 랜덤으로 안나오고
    OOOOOOOOOOOOOOOOOOOOXXXXXXXXXXXXXXXXXXXXXXXXX이렇게 나뉘어서 나옵니다!!
    반복문을 1000번으로 바꾸어도 그러는데.. 무슨 이유가 있을까요??

    • 여행자를꿈꾸며 2019.09.05 17:46 신고

      안녕하세요
      글이 조금이라도 도움이되었다니 다행입니다.
      질문하신 부분에 대한 실습 코드를 볼 수 있다면 답변에 도움이 될것 같습니다.

  2. E.asiest 2019.09.05 22:43 신고

    https://easy7.tistory.com/437 제 기록용 블로그입니다!
    여기서 2. 경쟁조건 해보기 보시면
    제 오류를 보실수 있습니다 ㅠㅠ

    • 여행자를꿈꾸며 2019.09.05 23:48 신고

      기대하는 결과가 나오지 않은 이유는 스케줄링과 관계가 있어 보입니다.

      OS는 설정된 스케줄링 정책에 따라서 각 프로세스를 번갈아 가면서 일정 시간동안 조금씩 실행할 것입니다.

      실습코드를 보면 부모 프로세스와 자식 프로세스가 각각 하는 일은 for문 100번 돌면서 0과 X를 출력하는 것입니다. 이정도는 스케줄링 한싸이클안에 끝낼 수 있는 양으로 생각됩니다.

      따라서 아래 2가지 방법은 테스트를 해볼 수 있습니다.
      1. 부모와 자식 프로세스의 for문을 1000000 횟수만큼 돌려보세요 아마도 0과 X가 번갈아 출력될 것입니다.(혹시 결과가 같다면 반복문 횟수를 더 늘려보세요)

      2. 부모와 자식 프로세스에서 sleep(1) 함수를 각각 추가해 보세요 그럼 기대하는 결과를 볼 수 있을 것입니다. 프로세스가 1초 동안 쉬는 동안 스케줄링 정책에 의해 다른 프로세스가 CPU를 점유하게 되기 때문입니다.

      부모
      for(a=0;a<100; a++) {
      if(a%2 == 0) printf("0\n");
      sleep(1);
      }

      자식
      for(b =0;b<100;b++) {
      if(b%2 == 1) printf("X\n");
      sleep(1);
      }

  3. E.asiest 2019.09.09 00:24 신고

    반복문을 백만번 돌리니까 됩니다!! 정말 감사드립니다ㅎㅎ
    cpu 스케줄링의 성능이 이렇게 좋은줄 처음 알았네요ㅎㅎ



    2번째 해결책도 해보았는데요(반복문 100번, sleep(1) 추가)
    출력값이 하나씩 나오지 않고 1분 가량 후에 한번에 출력되었습니다!
    물론 OOOOOOOOOOXXXXXXXXXXXX 프로세스 경쟁하는 것은 보지 못했습니다.! 100번은 정말 한 사이클로 가능한 것 같습니다!
    10000번 sleep(1)으로 돌려봤는데.. 시간이 너무 걸려서 포기했습니다

    친절한 답변 감사드립니다!

    • 여행자를꿈꾸며 2019.09.10 20:02 신고

      2번 테스트 코드를 작성하실때,
      printf("X \n");
      printf("O \n");
      위의 printf에서 개행문자가 보이지는 않지만 아무튼 "역슬래쉬 + n"를 넣어주어야 1초에 한번씩 O, X가 번갈아 출력될 것입니다.

      그렇게 하지 않았을 때 마지막에 한꺼번에 OOOOOOXXXXXXX 가 출력되는 것은 부모와 자식 각 프로세스가 종료되면서 각 프로세스의 stdout 버퍼에 쌓여있던 것들을 flush 하고 종료되었기 때문인것 같습니다

  4. E.asiest 2019.09.10 21:12 신고

    제가 그렇습니다... 옮겨쓰면서 개행문자를 경시했어요 ㅠㅠㅠ 개행문자가 이렇게 중요할줄은 몰랐어요!!!
    개행문자 有 + 반복문 100개 -> O사이에 X하나 나왔어요!

    개행문자 有 + 반복문 100개 + sleep(1) -> 너무 착하게 O하나 X하나 O하나, X하나 잘 나옵니다!!!!!

    정말 감사합니다 고수님 ㅠㅠㅠㅠ
    궁금증이 완전 시원하게 풀렸습니다!!!!!
    종종 들러서 추천하고 가겠습니다!!

+ Recent posts