리눅스데브코스 [5주차 - 3]<리눅스 명령어 사용법 실시간 실습 2>

심우열·2023년 5월 3일
0

1. 프로세스 계층

  1. 한개의 프로세스는 다른 프로세스를 생성 할 수 있다.(부모-자식 간의 관계처럼)
  2. Unix는 이러한 계층구조를 프로세스 그룹이라고 말함
  3. 윈도우에는 이러한 프로세스 계층 구조가 없다

프로세스 목록을 확인하는 방법

  1. 유닉스 계열에서는 ps
  2. 윈도우에서는 taskmgr

2. fork() 시스템 콜

  1. 자식 프로세스를 생성할때 호출되는 시스템 콜
  2. 부모의 전체 가상 주소 공간을 복사하여 자식 프로세스를 생성
  3. 자식 프로세스를 관리하기 위해 내부 데이터 구조를 복사함
  4. 부모 프로세스는 자식 프로세스의 pid를 얻음
  5. 자식 프로세스는 0의 값을 갖는다

3. fork() 의 예시

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

int main(){
    int pid;

    pid = fork();
    if(pid == 0){
        /*child*/
        printf("Child of %d is %d\n", getppid(), getpid());
    }

    else{
        /*parent*/        
        printf("I am %d. My child is %d\n",getpid(), pid);
    }

    return 0;        
}

4. 실습 1

1. 코드_1

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

int main(){

    int ans=0;
    int n;
    printf("0에서 몇까지 더할까요?");
    scanf("%d",&n);

    int pid; 
    //fork로 자식 프로세스 생성
    pid = fork();

    if(pid>0){
        /*parent*/
        int sum=0;
        for(int i=1;i<=n;i++)
        {
            sum += i;
        }
        printf("0에서 %d까지의 합은 %d입니다.\n",n,sum);
        ans += sum;
    }
    else if(pid==0){
        /*child*/
        int fac=1;
        for(int i=1;i<=n;i++)
        {
            fac *= i;
        }
        printf("%dfactorial의 값은 %d입니다.\n",n,fac);
        ans += fac;
    }
    else{
        /*fork fail*/
        printf("fork Fail! \n");
        return -1;
    }
    printf("정답은 %d 입니다.\n",ans);
    return 0;

}

2. 실행 결과_1

3. 문제점_1

부모 프로세스에서 sum 연산을 진행하고 자식프로세스에서 fac 연산을 진행해서 그 값을 합하여 ans 값을 출력하려고 하였으나, "정답은 15입니다", "정답은 120입니다" 와 같이 ans 값이 합산되어 출력되지 않고 2번에 걸쳐 합산되지 않은채로 출력되는 것을 알 수 있었다.

왜 그럴까?

1. 각각의 프로세스에 마지막 ans를 출력하는 부분이 따로 주어진다.

두개의 자식 프로세스를 생성해서 sum 연산과 fac연산을 진행하고 부모프로세스에서 자식프로세스의 종료를 기다린 후 두 값을 더해서 출력하자

2. 부모 프로세스가 자식 프로세스의 종료시까지 기다리지 못한다.

자식 프로세스의 종료 여부를 확인하기 위해 wait() 사용해보자
wait() 란?

4. 수정_2

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

int main(){

    int fac=1;
    int sum=0;
    int n;
    printf("0에서 몇까지 더할까요?");
    scanf("%d",&n);

    int pid;
    //fork로 자식 프로세스 생성
    pid = vfork();

    if(pid==0){
        /*child*/
        for(int i=1;i<=n;i++)
        {
            fac *= i;
        }
        printf("%d factorial의 값은 %d 입니다.\n",n,fac);
        exit(0);
    }
    /*parent*/
    wait(NULL);
    for(int i=1;i<=n;i++)
        sum += i;

    printf("0 에서 %d 까지의 sum은 %d 입니다.\n",n,sum);
    printf("정답은 %d 입니다.\n",sum+fac);

    return 0;

}

5. 실행결과_2, 실패

6. 문제점_2

이렇게 해도 부모프로세스의 fac 값은 자식 프로세스의 fac 연산결과에 영향을 받지 않음

자식 프로세스는 부모프로세스의 자원을 공유하는 것이 아니라 복제해 오는 것이기 떄문.

IPC를 사용해야 함

IPC란?

*쓰레드를 이용하는것이 더 좋은 방법이긴 함, 쓰레드는 자원 공유 가능

profile
Dev Ops, "Git, Linux, Docker, Kubernetes, ansible, " .

0개의 댓글