본문 바로가기

study

Operating System | 프로세스의 생성, 삭제, 좀비 & 고아 프로세스, 메시지 패싱 시스템, 파이프 (10월 첫째 주)

 

프로세스 생성 Process Creation

  • 부모 프로세스가 자식 프로세스를 만든다. (프로세스는 트리 구조로 되어 있음)
  • PCB에 저장된 pid (process identifier) 값으로 프로세스를 식별한다. (운영체제가 정해 준 고유 번호)
  • 자원 공유 옵션 - a. 부모와 자식이 서로 모든 자원을 공유하는 옵션 b. 자식들이 부모 자원의 부분집합을 공유하는 옵션 c. 부모와 자식이 자원을 공유하지 않는 옵션
  • 실행 옵션 - a. 부모와 자식이 동시에 실행하는 옵션 b. 부모가 자식이 terminate 될 때까지 기다리는 옵션
  • 주소 공간 옵션 - a. 자식이 부모의 복사본인 옵션 b. 자식이 로드된 프로그램을 갖고 있는 옵션

 

UNIX에서의 프로세스 생성 Process Creation in UNIX

  • fork 시스템 호출은 새로운 프로세스를 만들어내는 기능을 한다.
  • 새로운 프로세스는 원래의 프로세스 주소 공간의 복사본을 갖고 있다.
  • fork : 현재 돌아가고 있던 프로세스를 복사해서 다른 프로세스를 만든다.
  • exec : 프로세스로 하여금 다른 binary를 가지고 새로 시작하도로 한다. 자식 프로세스는 exec을 통해 내용을 모두 바꾼다.

프로세스 생성과 삭제

 

프로세스 삭제 Process Termination

  • 프로세스는 마지막 statement를 실행하고 exit 시스템 호출을 이용하여 운영체제로 하여금 삭제하도록 한다.
  • 부모는 자식에게서 wait 를 통해 상태 값을 받을 수 있다.

 

좀비 프로세스 Zombie Process

  • 좀비 프로세스(혹은 defunct 프로세스)는 실행을 마쳤지만 프로세스 테이블에서 제거되지 않은 상태로 남게 된 프로세스를 뜻한다.
  • 프로세스가 종료되었지만, 부모가 wait 을 통해 상태를 보고받지 못한 경우이다. (대개 버그나 코딩 에러 때문)
  • 부모는 실행되고 있으나, 자식은 죽은 경우이다. 

 

고아 프로세스 Orphan Process

  • 부모가 자식 프로세스보다 먼저 종료되면 그 자식 프로세스는 고아 프로세스가 된다.
  • 이때 init 프로세스가 새로운 부모가 되고, 고아 프로세스를 종료시키기 위해 wait 함수를 호출한다. (좀비 프로세스가 되는 것을 방지하기 위해)
  • 부모(init 프로세스가 아닌 original one)가 죽었으나, 자식은 실행되고 있는 경우이다.

 

Inter-Process Communication (IPC)

  • 프로세스는 독립적 혹은 서로 협력하며 동작할 수 있다. 협력하는 프로세스들은 통신하며 서로에게 영향을 미친다.

메시지 패싱과 공유 메모리를 이용한 프로세스 구조

 

 

메시지 패싱 시스템 Message Passing System

  • 같은 주소 공간을 사용하지 않고 서로 소통하는 프로세스들이다.
  • 송신 프로세스가 정보를 받는 수신 프로세스에게 커널을 통해 정보를 전달하며, 수신 프로세스도 커널에 접근해 정보를 수신한다.
  • Context switch가 발생하기 때문에 속도가 느리다.
  • 커널이 기본적인 기능을 제공하므로 공유 메모리 방식에 비해선 구현이 쉽다.
  • 메시지 패싱을 디자인할 때 고려해야 할 점은 다음 세 가지이다.
  1. 명명 Naming ; 이 프로세스에 어떤 이름을 붙여야 하는가?
  2. 동기화 Synchronization ; 메시지 수신과 같은 두 프로세스들이 어떻게 소통하는가?
  3. 버퍼링 Buffering ; 받은 정보들을 어떻게 임시적으로 저장하는가?

 

명명 Naming

  • 통신을 원하는 프로세스들은 서로를 가리킬 수 있는 방법이 있어야 한다. 직접 혹은 간접 통신이 존재한다.
  • 직접 통신을 위해서는 통신의 수신자와 송신자의 이름을 명시해야 한다.

send (P, message) - 프로세스 P에게 메시지를 전송한다.

receive (Q, message) - 프로세스 Q에게서 메시지를 수신한다.

 

  • 통신을 원하는 두 프로세스 사이에 연결이 자동적으로 구축된다. 프로세스들은 통신하기 위해 서로 상대방의 신원(identification)만 알면 된다.
  • 연결은 정확히 두 프로세스 사이에만 이루어진다.
  • 통신하는 한 쌍의 프로세스 사이에는 정확하게 하나의 연결이 존재해야 한다.
  • 이러한 통신은 대칭성이 두드러진다. 송신자와 수신자 모두 서로의 이름을 명시해야 한다.

 

  • 그러나 주소 지정 시 비대칭 형식을 사용할 수도 있다. 수신자는 송신자에 대해  명시할 필요가 없다는 것이다.

send (P, message)

receive (id, message) - 임의의 프로세스들로부터 메시지를 받는다. 변수 id는 통신을 발생시킨 프로세스의 이름으로 설정된다.

 

  • 직접 통신의 단점은 프로세스를 정확히 지정함으로써 모듈화가 제한된다는 것이다. 

 

  • 간접 통신은 메시지가 메일 박스를 통해 수송신하는 통신 방식이다.
  • 각 메일박스는 고유 아이디가 있으며, 메일박스를 공유하고 있는 프로세스들만이 통신할 수 있다.

send (A, message) - 메일박스 A에 메시지를 송신한다.

receive (A, message) - 메일박스 A에게서 메시지를 수신한다.

 

  • One-to-Many - 프로세스들이 메일박스에게서 수신할 수 있다.
  • Many-to-One - 다수의 프로세스들이 하나의 수신 프로세스로 송신한다.
  • Many-to-Many - 다수의 프로세스들이 다수의 수신 프로세스로 송신한다.

 

동기화 Synchronization

  • 메시지 패싱은 봉쇄형이거나, 비봉쇄형일 수 있다. 봉쇄형은 동기식(synchronous)이며, 비봉쇄형은 비동기식(asynchronous)이다.
  • 봉쇄형 송신 - 송신하는 프로세스는 메시지가 수신 프로세스 또는 메일박스에 의해 수신될 때까지 봉쇄된다.
  • 비봉쇄형 송신 - 송신하는 프로세스는 메시지를 보내고 작업을 재시작한다.
  • 봉쇄형 수신 - 메시지가 이용 가능할 때까지 수신 프로세스는 봉쇄된다.
  • 비봉쇄형 수신 - 송신하는 프로세스는 유효한 메시지 또는 널(null)을 받는다.

 

버퍼링 Buffering

  • 연결 안의 메시지들을 보관하고 있는 큐(queue)이다.
  • 생산자-소비자 문제는 두 프로세스가 동시에 동작할 때 일어나는 이슈이다. 보통 정보가 생산되는 속도가 소비하는 속도보다 빠르기 때문에 동기화 문제가 발생하는데, 이를 해결하기 위해 생산된 데이터를 담아 두는 버퍼를 사용한다.
  • Zero capacity - 큐의 최대 길이가 0이다. 즉, 연결 자체 안에 대기하는 메시지들을 가질 수 없다. 이 경우 송신자는 수신자가 메시지를 수신할 때까지 기다려야 한다. (rendezvous)
  • Bounded capacity - 큐는 유한한 길이 n을 가진다. 즉, 최대 n개의 메시지가 그 안에 들어 있을 수 있다. 새로운 메시지가 전송될 때 큐가 만원이 아니라면, 메시지는 큐에 놓이며(메시지가 복사되든지 또는 메시지에 대한 포인터가 유지된다), 송신자는 대기하지 않고 실행을 계속한다. 그렇지만 연결은 유한한 용량을 가진다. 연결이 만원이면, 송신자는 큐 안에 가용한 공간이 생길 때까지 반드시 봉쇄되어야 한다.
  • Unbounded capacity - 큐는 잠재적으로 무한한 길이를 가진다. 따라서 메시지들이 얼마든지 큐 안에서 대기할 수 있다. 송신자는 결코 봉쇄되지 않는다.

 

파이프 Ordinary Pipe

  • 파이프는 한 프로세스를 다른 프로세스에 연결하는 unidirectional byte 스트림이다.
  • 한쪽 방향으로만 통신이 가능하므로 읽기나 쓰기 중 하나만 가능하다. 송수신 둘 다 원하면 두 개의 파이프를 만들어야 한다.

파이프

익명 파이프 Anonymous Pipe

  • 통신할 프로세스를 명확하게 알 수 있는 경우에만 통신이 가능하다. (부모-자식인 경우)

익명 파이프

Named 파이프 Named Pipe

  • 꼭 부모-자식 관계가 아니더라도 파이프를 이용해 통신할 수 있다.
  • open, close, read, write과 같은 파일 명령어들로 하여금 파일처럼 처리될 수 있다.
  • mkfifo 혹은 mknod 명령어로 생성된다.