운영체제(OS)

[운영체제] 7. 프로세스 생성? 자식 부모 관계를 이용한 협력?

김민석(갈레, 페퍼) 2022. 2. 22. 18:01
반응형

<운영체제 TIL 목록>
1. 운영체제란? 목적? 분류? 
2. 인터럽트란? 컴퓨터 시스템 동작원리로 알아보자.
3. 하드웨어, 메모리 및 메모리 보안 방법?
4. 프로그램의 구조, 실행 과정?

5. 인터럽트, 문맥 교환(컨택스트 스위칭), PCB 정의와 차이?

6. 프로세스란? 5 or 6가지 상태? 스케줄러? 

7. 프로세스 생성? 자식 부모 관계를 이용한 협력? 
8. 스레드, 멀티스레드란? 프로세스와의 차이?

8. CPU 스케줄링란? 종류 평가 기준?

9. ''업데이트 예정"

 

1. 프로세스 생성?

생성 주체

- 운영체제: 컴퓨터를 시작하면 바로 시작되는 프로그램.

- 이미 존재하는 프로세스: 운영체제에 의해 실행되는 프로세스 다음에 실행되는 모든 프로세스.

 

자원 획득 방법

운영체제의 자원 획득 방법은 크게 두가지가 있다. 대부분의 프로세스는 운영체제로부터 직접 자원을 할당 받는다. 드문 경우 부모 프로세스와 협력하기 위해 부모 프로세스와 자원을 공유하기도 한다.

  • 운영체제로부터 직접 자원 할당
  • 부모 프로세스와 자원 공유(드문 케이스)

생성 함수

- fork() 시스템 콜

  • 역할: 자식 프로세스를 생성할 때 부모 프로세스의 내용을 그대로 복제하는 시스템 콜 함수다. 엄밀히 말하자면 운영체제가 프로세스를 관리하기 위한 프로세스ID를 제외하고 복제한다. 생성된 자식 프로세스는 PC 마저 부모 프로세스와 같다.
  • 수행 과정
    1. cpu가 fork 함수를 실행하면 cpu 제어권이 커널로 넘어가게 된다. 프로세스 복제는 메모리 관련 작업이기에 커널이 이를 대행한다.
    2. 커널은 fork 함수를 호출한 프로세스를 복제하여 자식 프로세스를 생성하고 부모-자식 관계를 설정한다.
  • 단점?: 단점이라기보단 캡슐화가 잘되있어서 생겨나는 현상이다. fork는 부모 프로세스 그대로 자식프로세스를 만들기 때문에 자식 프로세스로 새로운 코드를 실행하려면 if와 같은 분기를 사용하여 코드를 구현해야한다(자신이 부모인지 자식인지는 fork 리턴 값으로 알 수 있다). 이는 사실 단일 책임원칙을 생각하더라도 좋지 않은 구현이다. 따라서 fork는 자식-부모 관계를 가지는 프로세스 생성에만 책임을 가진다.

<그림1. fork 시스템 콜로 인한 부모 자식 분기>

 

- exec() 시스템 콜

  • 역할: 현재 실행하던 프로세스의 상태를 모두 잊어버리고 주소 공간을 새로운 프로그램으로 덮어씌운 후, 프로그램 처음부터 실행을 시작한다.
  • 수행 과정
    1. cpu가 exec()을 만나면 메모리 값 변경을 해야하기 때문에 커널이 필요하게 되어 시스템 콜을 실행한다.
    2. 커널은 프로세스 ID를 그대로 두고 프로세스 문맥과 프로세스 구조 데이터(코드, 데어터, 스택, 힙)를 바꾼다. 프로세스 ID를 그대로 두는 이유는 exec()가 새로운 프로세스를 생성하는게 아니기 때문이다. 프로세스 안에 있는 내용물은 커널이 신경 쓸 필요가 없다. 따라서 커널 입장에선 프로세스 ID를 바꿀 이유가 없다.

<그림2. exec() 시스템 콜>

 

 

기타 함수

- wait() 시스템 콜

  • 역할: 부모와 자식 프로세스가 동기화가 필요할 때 wait 시스템 콜을 사용하여 부모 프로세스를 block 상태로 만든다. 부모가 자식 프로세스를 생성할 때는 자식 프로세스의 작업을 이용해야 자신의 작업을 다시 실행할 수 있는 경우가 있다. 이때 부모 프로세스는 자식 프로세스가 끝날 때까지 기다리기 위해 wait 시스템 콜을 사용한다. 

<그림3. wait() 시스템 콜>

 

2. 프로세스 종료

 부모 프로세스가 종료되면 자신의 자원을 먼저 정리하기 전에 자식 프로세스를 먼저 정리한다. 이를 구현하기 위해 부모-자식 프로세스는 트리 관계로 구성돼있다. 루트 노드 프로세스를 정리하려면 리프 노드에 있는 프로세스부터 차례대로 정리해야하는 구조다. 이로 인해 컴퓨터를 끄려면 운영체제 시작시에 실행된 프로세스에 의해 시작된 자식 프로세스들이 전부 종료되야한다.

 

자발적 종료

- 상황: 프로세스의 코드를 cpu가 모두 실행하면 프로세스는 종료되어야 한다. 프로세스가 exit() 시스템 콜을 실행하면 커널은 프로세스로부터 자원을 회수하고 시스템 내에서 해당 프로세스를 정리한다.

- 함수: exit()

- Tip: exit()는 코드에 명시적으로 적어서 호출할 수도 있지만, 프로그램의 종료되는 지점에 컴파일러가 자동으로 삽입하기도 한 코드로 호출될 수 있다.

 

비자발적 종료

- 상황

  • 자식 프로세스가 한계 이상의 자원을 요구
  • 자식 프로세스의 작업이 필요하지 않은 경우
  • 부모 프로세스가 종료될 경우

- 함수: abort()

 

3. 자식 부모 관계를 이용한 협력?

원칙

 프로세스는 서로 메모리에 영향을 주지 않는 것이 원칙이다.

예외

 프로세스간 통신이 이뤄지면 더 성능 효율이 좋아지는 경우가 있다. 이때 보안을 준수하는 것이 중요하며 그 방법에 대해 알아보자.

IPC(Inter-Process Communication)

- 요약: 하나의 컴퓨터 안에서 실행중인 서로 다른 프로세스간 통신

- 보장 필요 사항: 의사소통 기능, 동기화

- 방법

  • 메세지 전달
    • 요약: 프로세스 간 공유 데이터를 일체 사용하지 않고 메세지를 주고 받으며 통신. 메세지 전달은 상대방 메모리에 영향을 끼칠 수 있기 때문에 커널이 대리한다.
    • 직접 통신: send(P, message)와 receive(Q, message) 메세지 내용과 받을 상대방을 명시적으로 표시.
    • 간접 통신: 메세지를 프로세스에게 직접 받는게 아닌 메일 박스 혹은 포트에 담긴 것을 받는 방식.
  • 공유 메모리
    • 요약: 프로세스들이 주소 공간의 일부분을 공유한다. 메모리 A, B는 독자적인 주소 공간을 가지고 있지만 물리적인 메모리에 매핑될때 같은 곳으로 설정되는 구조다. 공유 메모리는 커널이 관여하지 않기 때문에 데이터 일관성 문제가 생길 수 있다. 따라서 프로세스들 끼리 동기화 문제를 해결해야한다.

 

<그림4. 프로세스간 통신>

반응형