📀 운영체제

04. 프로세스의 생성: Chapter 3. Processes (Part 2)

락꿈사 2022. 5. 16. 18:26

3.3 프로세스 실습

실습1

#include <stdio.h>
#include <unistd.h>
int main()
{
    pid_t pid;
    pid = fork();
    printf("hello, process! %d\n", pid);
    return 0;
}

  • child process의 pid: 29809 (부모 프로세스가 출력)
  • fork(): fork() 시스템 콜을 하면 parent 프로세스의 주소 공간을 그대로 복사하고 부모 프로세스는 계속 실행됨.

 

실습 2

#include <stdio.h>
#include <unistd.h>
int main()
{
    pid_t pid;
    pid = fork();
    if (pid > 0) 
        wait(NULL);
    printf("hello, process! %d\n", pid);
    return 0;
}

  • wait(): wait() 시스템콜을 호출하면 부모 프로세스가 자식 프로세스가 끝날 때 까지 wait 큐에서 기다림
  • 그 결과 자식 프로세스가 먼저 종료되고(hello, process! 0 출력) 그 뒤에 부모 프로세스가 종료됨(hello, porcess! 31891 출력)

 

연습문제 3.1

#include <stdio.h>
#include <unistd.h>
int value = 5;

int main()
{
    pid_t pid;
    pid = fork();
    if (pid == 0){
        value += 15;
        return 0;
    }
    else if(pid > 0){
        wait(NULL);
        printf("PARENT: value=%d\n", value);
        return 0;
    }
}

  • 자식 프로세스는 value = 5일 때 자식 프로세스의 메모리 공간에 생성됨
  • 부모 프로세스는 wait() 시스템콜을 통해 wait큐에서 자식 프로세스가 종료될 때 까지 기다림
  • 자식 프로세스가 실행되고 자식 프로세스의 value=20이 됨
  • 자식 프로세스가 종료되면 wait 큐에 있던 부모 프로세스로 context switch가 일어남
  • 이 때 부모 프로세스의 value=5 이므로 5를 출력하고 종료됨

 

연습문제 3.2

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

int main()
{
    fork();
    fork();
    fork();

    return 0;
}
  • 맨 처음에 p0를 복사한 p1 생성 (1번째 fork())
  • 그 다음에 p0, p1를 복사한 p2, p3 생성 (2번째 fork())
  • 그 다음에 p0, p1, p2, p3를 복사한 p4, p5, p6, p7 생성 (3번째 fork())
  • 총 8개가 생성됨

 

연습문제 3.11

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

int main()
{

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

    return 0;
}
  • 이 때 만들어지는 프로세스의 수는 2^4개로 16개임.
#include <stdio.h>
#include <unistd.h>
#include <wait.h>

int main()
{
    int i;
    
    for(i=0; i<4; i++){
        fork();
    }
    printf("Hello, fork!\n");
    return 0;
}

  • Hello, fork가 16개가 출력된 것을 통해 확인할 수 있음

 

연습 문제 3.12

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

int value = 5;

int main()
{
    pid_t pid;
    pid = fork();

    if (pid == 0){
        execlp("home/C++", "ls", NULL);
        printf("LINE J\n");
    }
    else if(pid > 0){
        wait(NULL);
        printf("Child Complete\n");
    }
    
    return 0;
}
  • 이 소스에서 printf("LINE J")는 실행되지 않음.
  • execlp 명령어를 통해 child 프로세스 메모리 공간의 내용이 ls 명령어로 교체했기 때문.
  • (근데 나는 왜 출력이 되는지???)

 

 

연습 문제 3.13

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

int value = 5;

int main()
{
    pid_t pid, pid1;
    pid = fork();

    if(pid == 0){
        pid1 = getpid();
        printf("child: pid = %d\n", pid);
        printf("child: pid1 = %d\n", pid1);
    }
    else if(pid > 0){
        wait(NULL); 
        pid1 = getpid();
        printf("parent: pid = %d\n", pid);
        printf("parent: pid1 = %d\n", pid1);
    }
    
    return 0;
}

  • getpid() 시스템 콜은 현재 프로세스의 pid를 가져옴
  • 그러므로 pid1은 자식 프로세스에서는 자식 프로세스의 pid(71637)가 되고 부모 프로세스에서는 부모 프로세스의 pid(71637)가 됨

 

연습 문제 3.16

#include <stdio.h>
#include <unistd.h>
#include <wait.h>
#define SIZE 5

int nums[SIZE] = {0,1,2,3,4};

int main()
{
    pid_t pid;
    int i;
    pid = fork();

    if(pid == 0){
        for(i=0; i<SIZE; i++){
            nums[i] *= i;
            printf("CHILD: %d \n", nums[i]);
        }
    }
    else if(pid > 0){
        wait(NULL);
        for(i=0; i<SIZE; i++){
            printf("PARENT: %d \n", nums[i]);
        }
    }
    return 0;
    
}

  • 이 경우에서 항상 자식 프로세스가 먼저 나오는 것은 아님
  • fork()를 했을 경우 context switch가 일어나면 부모 프로세스가 먼저 실행될 수 있음