Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++ fork()와 wait()를 활용한 프로세스 역순 실행 방법

fork() 시스템 콜은 하나의 프로세스를 두 개의 프로세스로 분리하는 데 사용됩니다. fork() 함수가 0을 반환하면 자식 프로세스이고, 그렇지 않으면 부모 프로세스입니다.

이번 예제에서는 프로세스를 네 번 분할하고, 이를 아래에서 위로(bottom-up), 즉 손자 → 자식 → 부모 순서로 실행하는 방법을 알아보겠습니다.

동작 원리

먼저 fork() 함수를 연속으로 두 번 호출합니다. 첫 번째 fork() 호출로 하나의 자식 프로세스가 생성되고, 두 번째 fork() 호출로 또 다른 자식 프로세스가 생성됩니다. 이후 내부의 fork()는 자동으로 이들의 손자(grandchild) 프로세스까지 만들어냅니다. 결과적으로 메인 프로세스 1개, 자식 프로세스 2개, 손자 프로세스 1개, 총 4개의 프로세스가 만들어집니다.

여기에 wait() 함수와 sleep() 함수를 사용해 실행 지연을 주면, 프로세스들이 의도한 대로 아래에서 위로 순차적으로 종료되도록 제어할 수 있습니다.

예제 코드

#include <iostream>
#include <sys/wait.h>
#include <unistd.h>
using namespace std;

int main() {
    pid_t id1 = fork(); // 연속된 두 번의 fork로 4개 프로세스 생성: 부모, 자식 둘, 손자 하나
    pid_t id2 = fork();

    if (id1 > 0 && id2 > 0) { // 두 값 모두 0이 아니면 부모 프로세스
        wait(NULL);
        wait(NULL);
        cout << "Ending of parent process" << endl;
    } else if (id1 == 0 && id2 > 0) { // 첫 번째 값이 0이면 첫 번째 자식
        sleep(2); // 두 번째 자식이 먼저 실행되도록 2초 대기
        wait(NULL);
        cout << "Ending of First Child" << endl;
    } else if (id1 > 0 && id2 == 0) { // 두 번째 값이 0이면 두 번째 자식
        sleep(1); // 1초 대기
        cout << "Ending of Second child process" << endl;
    } else {
        cout << "Ending of grand child" << endl;
    }
    return 0;
}

실행 결과

soumyadeep@soumyadeep-VirtualBox:~$ ./a.out
Ending of grand child
Ending of Second child process
Ending of First Child
Ending of parent process
soumyadeep@soumyadeep-VirtualBox:~$

코드 설명

실행 결과를 보면 가장 마지막에 생성된 손자 프로세스가 먼저 종료되고, 그다음 두 번째 자식, 첫 번째 자식, 마지막으로 부모 프로세스가 종료되는 것을 확인할 수 있습니다.

  • 부모 프로세스(id1 > 0 && id2 > 0): wait(NULL)을 두 번 호출하여 모든 자식 프로세스가 종료될 때까지 기다립니다.
  • 첫 번째 자식(id1 == 0 && id2 > 0): sleep(2)로 2초간 대기한 후, 자신의 자식(손자)이 끝나기를 wait()로 기다린 뒤 종료합니다.
  • 두 번째 자식(id1 > 0 && id2 == 0): sleep(1)로 1초간 대기한 후 종료합니다.
  • 손자 프로세스: 별도의 대기 없이 즉시 종료됩니다.

이처럼 wait()sleep()을 적절히 조합하면 여러 프로세스의 실행 및 종료 순서를 효과적으로 제어할 수 있습니다.