시스템은 반드시 프로세스 생성, 종료, 그리고 프로세스 사이의 통신 등에 대한 메커니즘을 제공해야한다.
Process 생성
Parent process가 chidren process를 만든다.
이렇게 프로세스가 다른 프로세스를 만드는 것은 프리를 만드는 것과 유사하다.
일반적으로 프로세스는 pid(process identifier)로 식별되고 관리된다.
parent와 child 프로세스는 모든 resources를 공유할수도, 일부만 공유할수도, 또는 resources를 공유하지 않을 수도 있다.
🧈 예를 들어, Linux에서는 child process가 만들어질 때, parent의 모든 variables이 복사된다.
하지만, Lock을 걸어놓은 parent 프로세스의 부분은 공유하지는 않는다.
parent와 child process가 동시에 실행될 수 있지만, parent 프로세스는 모든 children 프로세스가 종료될 때 까지 기다린다.
🦪 children 프로세스는 끝나면 signal, interupt를 발생시키고, 이를 통해서 parent 프로세스에 child 프로세스가 종료되었음을 알린다. 그리고 parent process가 child 프로세스의 resources, 메모리를 free한다.
Process 종료
프로세스가 끝까지 실행되고, OS에 system call을 해 삭제를 요청한다.
child 프로세스는 할당이 해제되면서 parent 프로세스에게 status data와 pid를 보낸다.
프로세스의 resources는 OS에 의해서 할당해제된다.
🍕 만약, child 프로세스가 초과된 resources를 가지거나, child에게 할당된 작업이 더이상 필요하지 않으면 parent 프로세스가 child 프로세스를 system call을 통해서 종료할 수 있다.
child 프로세스는 parent 프로세스보다 먼저 종료될 수 없다.
🧁 OS는 parent 프로세스가 종료되면, 그의 모든 children 프로세스들을 종료시킨다. (cascading termination, 계단식 종료)
프로세스 종료는 OS에 의해서 시작된다.
wait하고 있는 parent 프로세스가 없는 프로세는 zombie 라고 한다.
🍸 wait() system call을 부르면 다시 정상으로 돌아온다.
만약 parent가 wait하지 않고 먼저 종료되어 버리면, 그 자식 프로세스는 orphan이 된다.
🎂 orphan이 되었을 때는, 임시 parent를 설정해 모든 orphan을 종료시켜 모든 resourecs를 free해야 한다.
Interprocess Communication
시스템내의 프로세스들은 독립적(다른 프로세스에 영향을 끼치지 않음)이거나 협력적이다.
프로세스들이 협력하는 이유는 정보를 공유하고, 모듈화를 통해서 스레드 프로그램(프로세스를 여러개로, 각각 스레드를 동시에 실행시켜 각각의 작업을 수행)을 실행하기 위한 modularity, 계산 속도 향상과 편의성을 도모하기 위함이다.
🍻 복잡하고 긴 프로그램을 여러개의 서브 작업으로 나누고 각각의 프로세스가 이를 실행하면 효율적이다. 하지만 이를 위해서 통신, 연산 결과의 공유가 필요하다.
이렇게, 협력이 필요한 프로세스들 사이에서는 IPC, 즉 interprocess communication 이 필요하다.
IPC를 위한 두 모델로 shared memory와 message passing이 있다.
Shared Memory
user space에 shared memory 공간을 만들어 데이터를 공유한다.
초기에만 system call이 필요하여 system call을 거의 필요로하지 않아 OS의 간섭이 적으며 trap, overhead역시 적다.
속도는 빠르지만, parent 프로세는 child 프로세스가 shared memory에 접근중일 때, 작업이 다 끝날 때 까지 기다려야 한다.
통신 속도가 빠르고, 많은 양의 데이터를 다룰때 유리하다.
사용자 사이의 통신으로, 통신이 사용자 프로세스의 제어하에 있고, 두 사용자간의 동기화 메커니즘이 필요하다.
🌼 사용자 프로세스가 shared memory에 접근할 때 작업을 동기화할 수 있는 메커니즘 필요 🌼
Message Passing
memory의 kernel에 공유 공간을 만들고 이곳의 message queue를 통해서 message를 send, receive하여 주고받는다.
kernel을 통해서 통신을 함으로, 많은 양의 system call을 반복하게 되고, overhead가 발생하고 속도가 저하된다.
하지만, 동기화가 필요없어 작은 양의 데이터를 통신하는데 유리하다.
사용자 프로세스 동기화를 하지 않는다. kernel에서 동기화 된다.
공유 변수에 의존하지 않는다.
메세지의 사이즈는 고정될 수도, 아닐 수도 있다.
🍘 message를 보내고 recieve가 될 때까지 block되는 방법이 있는데 이는 느리다. (synchronous)
🍙 message를 보내고 바로 다음 명령을 수행하는 asynchronous, 비동기적인 방법이 있는데 이때는 send가 완료되었는지 test하는 routine이 있어야 한다. blocking을 사용하는 방법보다 빠르다.