책/운영체제

운영체제 Ch03_'Process-2'

RyoTTa 2021. 1. 8. 03:13
반응형

3.3 프로세스에 대한 연산

3.3.1 프로세스 생성(Process Creation)

 실행되는 동안 프로세스는 여러 개의 새로운 프로세스들을 생성할 수 있다. 생성하는 프로세스를 부모 프로세스라 하고, 새로운 프로세스는 자식 프로세스라고 부른다. 계속해서 생성하다보면 결과적으로 프로세스의 트리를 생성한다.

 현대 운영체제는 PID라는 프로세스 식별자를 사용해 프로세스를 구별하는데 보통 정수로 되어있다. 

 

Process Tree of Linux System

 위 그림은 Linux 운영체제의 프로세스 트리를 보여주고 있으며 이름과 PID가 확인된다. 

 언제나 PID가 1인 systemd 프로세스가 모든 사용자 프로세스의 루트 부모 프로세스 역할을 수행하고 시스템이 부트될때 생성되는 첫 번째 사용자 프로세스이다. 

 

 일반적으로 프로세스가 자식 프로세스를 생성할 때, 자식 프로세스는 적절한 자원이 필요로 한다. 

 자원은 부모 프로세스의 자원을 분할하여 사용할 수있고, 운영체제로부터 직접 얻을 수 있다.

 

 또한, 자식 프로세스를 생성할때 두가지 가능한 방법이 존재한다.

 1. 부모는 자식과 병행하게 실행을 계속한다.

 2. 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다.

 

 새로운 프로세스들의 주소 공간 측면에서 볼 때 두 가지 가능성이 존재한다.

 1. 자식 프로세스는 부모 프로세스의 복사본이다(부모와 똑같은 프로그램과 데이터를 가진다)

 2. 자식 프로세스가 자신에게 적재될 새로운 프로그램을 가지고 있다.

 

 fork() System call

 

fork()

  새로운 프로세스를 생성한다.

  부모 프로세스의 프로그램 코드와 데이터를 완벽하게 복사한다.

  fork()이후에 부모와 자식은 동시에 실행된다.

  부모 프로세스의 fork() return value는 자식 PID이며, 자식 프로세스의 fork() return value는 0이다.

exec()

 

 exec() System call

  자신의 메모리 공간을 새로운 프로그램으로 교체한다.

  이진 파일을 메모리로 적재하고 그 프로그램의 실행을 시작한다.

  오류가 발생하지 않는 한 제어(Control)를 반환하지 않는다.

 

 Wait() System call

  부모 프로세스는 자식 프로세스가 종료될때까지 기다리며 Ready Queue로 옮겨진다.

 

fork()를 이용한 프로세스 생성 코드

 

위 코드의 실행 타임라인

 3.3.2 프로세스 종료(Process Termination)

  프로세스가 마지막 문장의 실행을 끝내고, exit() 시스템 콜을 사용하여 운영체제에 자신의 삭제를 요청하면 종료한다.    이 시점에서, 프로세스는 자신을 기다리고 있는 부포 프로세스에(wait()을 통해) status value을 반환할 수 있다.

 

  부모 프로세스는 여러가지 이유로 자식 중 하나의 실행을 종료할 수있다.

  1. 자식이 자신에게 할당된 자원을 초과하여 사용할때

  2. 자식에게 할당된 작업(Task)가 더 이상 필요 없을때

  3. 부모가 exit()을 요청하지만, 운영체제가 부모 exit() 이후 자식이 running 상태에 있는것을 허용하지 않을 때

 

  몇몇 시스템에서는 부모 프로세스가 종료된 이후 자식 프로세스가 존재할 수 없다.(Orphan Process) 이러한 시스템에서는 부모 프로세스가 종료되면 그것으로 부터 비롯된 자식 프로세스들도 모두 종료되어야 한다.(연쇄식 종료 Cascading termination) 

 

  프로세스가 종료하면 사용하던 자원은 운영체제가 다시 회수해 간다. 그러나 프로세스의 종료 상태가 저장되어있는 프로세스 테이블의 해당 항목은 부모 프로세스가 wait()을 호출할 때까지 남아 있게 된다. 이러한 프로세스를 좀비(Zombie)프로세스라 칭한다.

 

 위에서의 설명과 같이 부모 프로세스가 wait()대신 먼저 종료하게 되면 Orphan Process라고 한다. UNIX 시스템은 이러한 Orphan Process의 새로운 부모 프로세스로 systemd 프로세스를 지정한다. 또한 주기적으로 wait()을 호출해 종료 상태를 수집하고 PID와 프로세스 테이블 항목을 반환한다.

 

 

3.4 프로세스 간 통신(Interprecess Communication, IPC)

 IPC는 실행되는 병행 프로세스들 사이에 데이터와 정보를 공유할 수 있게한다.

 공유 메모리 기법과 메세지 패싱 기법 두가지 방법이 존재한다.

 

 공유 메모리 (Shared Memory)

  공유 메모리 영역을 구출할대 운영체제의 도움이 필요하다.

  프로세스는 간단히 메모리에 대해 read/write만 하면 된다.

  어떠한 업데이트도 즉시 타 프로세스에게 영향이 간다.

  공유 메모리 영역을 한번 구축해놓으면 이후에는 커널의 도움이 필요하지 않다.

 

 메세지 패싱(Message Passing)

  데이터를 메세지 형식으로 전송한다.

  충돌을 회피할 필요가 없기때문에 적은 양의 데이터를 교환하는데 유용하다.

  분산 시스템에 사용된다.

 

 

3.5 공유 메모리 시스템에서의 프로세스간 통신(IPC in Shared Memory Systems)

 프로세스는 주소공간에 필요한 공간을 준비한다.

 데이터를 공유할 다른 프로세스들은 해당 주소 공간에 attach만 하면 된다.

 프로세스 간의 메모리 액세스 제한을 제거하려면 운영체제의 개입이 필요하다.

 실제 사용시에는 OS의 개입이 전혀 필요하지 않다.

 

Shared Memory

 데이터를 생산하는 생산자 프로세스와 데이터를 소비하는 소비자 프로세스로 구분가능하다. 

 두 가지 유형의 버퍼가 사용된다. 무한 버퍼(Unbounded Buffer), 유한 버퍼(Bounded Buffer)

 무한 버퍼는 생산자 소비자 문제에서 버퍼의 크기에 제한이 없다. 즉 소비자는 새로운 항목을 기다려야할 필요는 있어도 생산자 측에서는 항상 새로운 항목을 생산할 수 있다.

 유한 버퍼는 버퍼의 크기가 고정되어 있다고 가정한다. 이 경우 버퍼가 비어있으면 소비자는 기다려야 하며, 모든 버퍼가 채워져 있으면 생산자가 기다려야한다.

 

 

3.6 메세지 패싱 시스템에서의 프로세스 간 통신(IPC in Message Passing Systems)

 운영체제가 메시지 전달 설비를 통해 프로세스간 서로 통신수단을 제공한다.

 동일한 주소 공간을 공유하지 않고도 프로세스들이 통신을 하고, 동작을 동기화할 수 있는 시스템 콜들을 제공한다.

 즉, 같은 시스템에서 실행되지 않는 분산 시스템에서 유용하다.

 

 3.6.1 명명(Naming)

  통신을 원하는 프로세스들은 서로를 가리킬 방법이 있어야 한다. 

  직접 통신(Direct Communication) 에서는 통신의 수신자 및 송신자의 이름을 명시해야한다.

  대칭형 직접 통신

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

   receive(Q, meesage) - 프로세스 Q로부터 메세지를 수신한다.

  비대칭형 직접 통신

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

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

 

  통신을 원하는 각 프로세스의 쌍들 사이에 연결이 자동으로 구축된다. 프로세스들은 통신하기 위해 상대의 id만 알면 된다.

  연결은 정확히 두 프로세스 사이에만 연관된다.

  통신하는 프로세스들의 각 쌍 사이에는 정확학세 하나의 연결이 존재해야 한다.

 

  간접 통신(Indirect Communication) 에서는 메일박스(Mailbox) 또는 포트(port)로 송수신한다.

  각 메일박스와 포트는 서로 약속된 고유 값을 가진다. 따라서 다수의 메일박스 및 포트를 사용해 다수의 프로세스와 통신이 가능하다.

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

   receive(A, meesage) - 메세지를 메일박스 A로부터 수신한다.

 

  한쌍의 프로세스들 사이의연결은 이들 프로세스가 공유 메일박스를 가질 때만 구축된다.

  연결은 두 개 이상의 프로세스들과 연관될 수있다.

  통신하고 있는 각 프로세스 사이에는 다수의 서로 다른 연결이 존재할 수 있고, 각 연결은 하나의 메일박스에 대응된다.

 

 3.6.2 동기화(Synchronization)

  Blocking send : 송신하는 프로세스는 메세지가 수신 프로세스 또는 메일박스에 의해 수신될 때 까지 Block된다.

  Nonblocking send : 손신하는 프로세스가 메세지를 보내고 작업을 재개한다.

  Blocking receive : 메세지가 이용 가능할 때까지 수신 프로세스가 Block된다.

  Nonblocking receive : 송신하는 프로세스가 유효한 메세지 또는 NULL 값을 수신한다.

반응형