[#5] 프로세스 관리 - 2

Posted by Neph's Blog on April 5, 2021

목차

  1. 목차
  2. 프로세스의 생성
    1. 부모 프로세스와 자식 프로세스
    2. 자원의 획득과 프로세스의 수행모델
    3. 주소 공간
    4. 프로세스의 생성 절차
    5. 프로세스의 종료 절차
    6. 프로세스의 강제 종료가 이루어지는 경우
    7. 자식 프로세스를 생성하는 과정
  3. 프로세스 간의 협력
    1. 독립적 프로세스
    2. 협력 프로세스와 협력 메커니즘
  4. IPC :: 메시지 전달 방식
    1. 메시지 전달 방식
    2. 직접통신과 간접통신
  5. IPC :: 공유메모리 방식
    1. 주소공간의 공유
    2. 일관성 문제

프로세스의 생성


부모 프로세스와 자식 프로세스

시스템이 부팅된 후 최초의 프로세스는 운영체제가 직접 생성하지만 그다음부터는 이미 존재하던 프로세스가 다른 프로세스를 복제 생성한다. 프로세스는 항상 자식 프로세스가 먼저 종료되고나서 부모 프로세스가 종료된다. 후손이 여러개인 (자식의 자식으로 이어지는 계층도가 긴) 프로세스의 경우에는 연쇄적으로 모든 후손 프로세스들을 종료시킨 뒤에 종료된다.


자원의 획득과 프로세스의 수행모델

생성된 프로세스가 작업을 수행하기 위해서는 자원이 필요하다. 운영체제로부터 직접 자원을 할당받는 경우도 있고 부모 프로세스와 자식 프로세스가 자원을 공유하는 경우(일부만 공유하는 경우, 전부를 공유하는 경우로 나뉨)도 있다. 프로세스가 수행되는 모델도 부모와 자식이 공존하며 수행되는 모델이 있고, 부모가 자식이 종료될때까지 기다리는 모델도 있다. 전자의 경우에는 CPU 획득을 위해 서로 경쟁하는 관계가 된다. 반면 후자의 경우에는 자식 프로세스가 종료되기 전까지 부모 프로세스는 봉쇄 상태에 머물러 있다가 자식 프로세스가 종료되면 준비 상태가 되어 CPU를 얻을 권한이 생기게 된다.


주소 공간

프로세스가 생성되면 독자적인 주소 공간을 갖게 된다. 부모 프로세스와 자식 프로세스는 별도의 주소 공간을 가지게 되는데 자식 프로세스는 부모 프로세스의 주소 공간 내용을 그대로 복사하여 생성된다.


프로세스의 생성 절차

유닉스에서는 fork() 시스템 콜을 통해 새로운 프로세스를 생성할 수 있는데 프로세스 ID를 제외한 모든 정보 즉, 운영체제 커널 내의 정보(PCB, 자원 등)와 주소 공간의 정보를 그대로 복사한다. 복제가 완료되면 그 위에 새로운 프로그램을 덮어씌울 수도 있는데 이 작업은 exec() 시스템 콜을 통해 이루어진다. (exec 작업은 필수가 아님)

자식 프로세스가 부모 프로세스와 달라지지 않는다면 굳이 복사를 진행할 필요가 없다. 따라서 자식 프로세스에서 변경이 진행될 때 복사를 진행하는 방식을 Copy-On-Write(a.k.a. COW)라고 한다.


프로세스의 종료 절차

프로세스의 종료는 크게 자발적 종료와 비자발적 종료로 구분된다. 자발적 종료가 이루어지는 경우, 프로세스는 명령을 모두 수행한 후 exit()이라는 시스템 콜을 진행한다(exit()은 프로그래머가 명시적으로 호출하지 않아도 프로그램 종료 지점에 컴파일러가 자동으로 삽입). 운영체제에게 exit()을 통해 자신이 종료될 수 있음을 알리면 운영체제는 자원을 회수하고 시스템 내에서 프로세스를 정리한다. 반면 비자발적 종료의 경우에는 부모 프로세스가 자식 프로세스의 수행을 강제로 종료하는데 이는 abort()라는 함수를 통해 이루어진다.


프로세스의 강제 종료가 이루어지는 경우

프로세스가 강제 종료되는 경우는 다음과 같다.

  1. 자식 프로세스가 한계치를 넘는 자원을 요구할 때
  2. 자식 프로세스에게 할당된 작업이 더 이상 필요하지 않을 때
  3. 부모 프로세스가 종료되는 경우

위와 다르게 부모 프로세스가 종료된 이후에도 실행되어야 할 프로세스가 있다면 해당 프로세스를 다른 프로세스의 자식으로 이양하는 작업이 필요하다.


자식 프로세스를 생성하는 과정

운영체제는 자식 프로세스의 생성을 위해 fork() 시스템 콜을 제공한다. fork() 시스템 콜을 하게 되면 fork() 함수를 호출한 프로세스와 똑같은 프로세스가 생성된다. 이렇게 생성된 자식 프로세스는 부모 프로세스의 모든 문맥을 동일하게 가지고 있으며 부모 프로세스의 주소 공간을 비롯해 프로그램 카운터 등 레지스터 상태, PCB 및 커널 스택 등 모든 문맥을 그대로 복제해 자식 프로세스의 문맥을 형성한다. 즉, 자식 프로세스는 부모 프로세스의 처음부터 수행하는 것이 아니라 현재 수행한 시점(PC 지점)부터 수행하게 된다. 이 둘을 구분하기 위해 부모 프로세스 식별자(pid)는 양수이며 자식 프로세스의 식별자는 0이라는 차이가 존재한다.

자식 프로세스가 부모와 다른 독자적 프로그램을 수행하도록 만들기 위해선 exec() 시스템 콜이 필요하다. exec() 시스템 콜은 지금까지 수행했던 상태를 잊어버리고 그 주소 공간을 완전히 새로운 프로그램으로 덮어씌운 후 처음부터 시작하도록 만들어준다. 즉, exec() 이전 시점까지 프로그램을 실행하다 exec()을 만나면 새로운 프로그램으로 넘어가서 그 프로그램을 실행하는 것이다.

wait() 시스템 콜을 통해 부모 프로세스와 자식 프로세스 간의 동기화가 가능하다. wait() 시스템 콜이 이루어지면 부모 프로세스는 자식 프로세스가 종료될 때까지 봉쇄상태에 들어가는데 일반적인 봉쇄 상태에서와는 다르게 자원을 기다리며 줄 서 있지 않고 자식 프로세스가 종료될 때까지 수면 상태에 머무른다. 자식 프로세스가 종료되는 순간 준비 큐에 재진입하여 CPU를 얻을 권한을 획득한다.



프로세스 간의 협력


독립적 프로세스

프로세스는 자신만의 주소 공간을 가지고 수행되며 다른 프로세스의 주소공간을 참조하는 것은 허용되지 않는다. 프로세스 복제 과정에서 부모 프로세스의 주소 공간을 자식 프로세스가 복제하지만 생성 이후에는 독자적인 주소 공간만을 참조해 코드를 수행하므로 독립적인 관계가 된다.

협력 프로세스와 협력 메커니즘

경우에 따라서는 프로세스들이 협력할 때 업무의 효율성이 증진될 수 있다. 이런 프로세스 간 협력 메커니즘은 대표적으로 운영체제가 제공하는 IPC(Inter-Process Communication)가 있다. IPC는 하나의 컴퓨터 안에서 실행 중인 서로 다른 프로세스 간의 통신을 의미하며 이러한 통신은 의사소통 기능과 동기화를 보장한다. 공유 데이터를 서로 다른 두 프로세스가 사용할 때 데이터 불일치의 문제를 예방하기 위해 하나의 프로세스가 공유 데이터의 값을 변경하는 동안 다른 프로세스는 그 데이터에 접근할 수 없도록 해야한다. IPC의 대표적인 방법으로는 메시지 전달 방식과 공유메모리 방식이 있다.



IPC :: 메시지 전달 방식


메시지 전달 방식

메시지 전달 방식은 공유 데이터를 사용하지 않고 커널이 메시지를 간접적으로 전달하는 방식이다. 메시지 통신을 하는 시스템은 커널에 의해 send(message)와 receive(message)를 제공받는데 이 두 연산을 통해 시스템 콜 방식으로 정보를 주고받는다.

통신이 필요한 두 프로세스는 커뮤니케이션 링크를 생성한 후 send()와 receive()를 통해 메시지를 주고받는다. 커뮤니케이션 링크는 물리적으로 구현될수도 있고 논리적으로 구현될수도 있다.

직접통신과 간접통신

메시지 전달을 통해 통신하는 방식에는 직접통신(direct communication)과 간접통신(indirect communication)이 있다. 이 둘의 차이는 연산의 인터페이스의 차이일 뿐 실제 메시지 전송이 이루어지는 내부 구현은 커널의 중재에 의해 사실상 동일하게 이루어진다.

직접통신에서는 통신하려는 프로세스의 이름을 명시적으로 표시한다. 커뮤니케이션 링크는 자동적으로 생성되고, 하나의 링크는 오직 한 쌍의 프로세스에게만 할당된다. 또한 각 쌍의 프로세스에는 오직 하나의 링크만이 존재하고 링크는 단방향성인 경우와 양방향성인 경우가 있지만 대부분 양방향성이다.

간접통신에는 메시지를 메일박스(mail box) 또는 포트(port)로부터 전달받는다. 각 메일박스에는 고유의 ID가 있으며 메일박스를 공유하는 프로세스들만 서로 통신할 수 있다. 간접통신의 경우 커뮤니케이션 링크는 프로세스 간에 메일 박스를 공유하는 경우에만 생성되는데 하나의 링크가 여러 프로세스들에게 할당될 수 있으며 각 프로세스의 쌍은 여러 링크를 공유할 수 있다. 링크는 단방향성과 양방향성 모두 존재하며 send/receive연산, 메일박스 삭제 연산 등이 지원된다.



IPC :: 공유메모리 방식


주소공간의 공유

공유메모리 방식에서는 프로세스들이 주소 공간의 일부를 공유한다. 원칙적으로는 각자 독립적인 주소 공간을 가지지만 운영체제가 시스템 콜을 통해 프로세스들이 주소 공간 중 일부를 공유할 수 있도록 해준다. 실제 구현은 두 프로세스가 서로 독자적인 주소 공간을 가지고 있지만 이 주소 공간이 물리적 메모리에 매핑될 때 공유메모리 주소 영역에 대해서는 동일한 물리적 메모리 주소로 매핑된다.


일관성 문제

공유메모리 방식은 프로세스간의 통신을 수월하게 해주지만 서로의 데이터에 일관성 문제가 발생할 수 있다. 이에 대해서는 커널이 책임을 지지 않으므로 프로세스들끼리 직접 공유메모리 접근에 대한 동기화 문제를 해결해야한다.