일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 정석
- DP
- 오에스
- coding
- 브루트포스
- 정석학술정보관
- 코딩
- 개발
- 자료구조
- cs
- 컴공과
- 구현
- 그래프
- 컴퓨터공학과
- 너비우선탐색
- Computer science
- bfs
- c++
- 백준
- vector
- Stack
- 코테
- 북리뷰
- OS
- 문제풀이
- Operating System
- 컴공
- 스택
- 오퍼레이팅시스템
- 알고리즘
- Today
- Total
Little Jay
[OS]Process Description and Control V (Creation, COW, Termination, Zombie, Orphan) 본문
[OS]Process Description and Control V (Creation, COW, Termination, Zombie, Orphan)
Jay, Lee 2022. 8. 2. 14:15Process Creation
Direct하게 Process를 생성하는 방법은 다음과 같다. 먼저 a.out과 PCB를 위한 메모리 공간을 할댕해준다. 이때 a.out 파일의 code와 data를 메모리에 오리고 Call Stack을 생성해준다. 그 다음 PCB를 Initialize해준다. 이제 Process가 생성되었으니 이를 ready list에 올리고 execute하면 된다. Process를 생성하는 데에는 다양한 이유가 있다. 먼저 New Batch Job, 즉 load&run하는 경우에 OS가 JCL과 같은 일련의 batch job control stream을 제공해준다. 또한 Interactive Logon에서 새로운 Process가 생성이 되는데 예를 들어 User가 새로운 Terminal에 로그인 할 때 Process가 생성된다. OS가 서비스를 제공해줄 때도 생성이 되는데, 이는 사용자가 대기 할 필요 없이 User Program을 대신해 기능할 수 있는 Process를 생성해준다. 예를 들어서 프린터의 Control을 제어해주는 Process등이 이에 해당한다. 마지막으로는 기존 프로세스에 의해 생성되는 fork가 있다. UNIX에서는 init process가 첫 번째 Process이자 Super Parent이다. 이는 booting될 때 Kernel에 의해서 생성이 된다. 이 Process를 바탕으로 해서 fork를 해 Process들이 생성이 된다.
Fork 기법은 정말 많이 사용이 된다. 이 기법을 Cloning이라고 한다. fork를 하게 되면 Child Process가 생성 되는데, 이때 생성된 Child Process는 Parent Process의 exact copy본 이지만 pid, relation등 Metadata의 차이가 존재한다. Fork를 호출해서 생성된 Process는 PCB를 ready list에 넣어 execute되기를 기대한다. 사실 이렇게 Copy본을 만들어 Process를 쉽게 생성할 수 있다는 장점이 있지만, 우리는 Copy본을 사용할 이유가 없기 때문에 내용을 Replace해줘야 한다. Execve는 이를 가능하게 해주는데, 이는 PID는 유지한 채 code, data, heap, stack 영역들을 바꾸어 Process를 Replace해줄 수 있다. 따라서 Fork는 Process의 단순한 생성의 역할을 하고 Process의 내용을 바꾸는 것은 Execve가 해주는 것이다. Exec가 성공하면 새로운 내용으로 덮어 씌워지는 것이기 때문에 기존의 코드들은 작동하지 않는다. 여기에 대해서는 시스템 프로그래밍 글에서 정리한 것이 있으니 같이 보면 좋을 것 같다.
Copy on Write(COW)
그러나 Fork는 Exact Copy본을 생성하는 것이기 때문에 생각보다 자원의 소모량이 많았다. 해당 사이즈의 크기 만큼 모조리 다 복사해야하는 것이기에 시간적으로 낭비가 있었다. 이를 해결하기 위해 vfork라는 기능이 있었지만, 현대 LINUX에서는 COW 방식을 채택하고 있다. COW 방식은 Optimization 방식 중 하나로 Process의 생성속도를 높인다. 먼저 Parent Page는 Shared된 상태로 마크가 되어 있다. 즉, Child Process는 단순히 Parent Page와 메모리를 공유하고 있는 상태인 것이다. 이때 Shared된 Page에 변화가 생기면 그제서야 OS는 이 페이지에 대한 Copy본을 만들게 된다. 이로서 각각의 Process는 다른 영역의 Resource를 사용할 수 있게 된다. 싱글 쓰레딩을 사용하는 경우에 COW를 Mutex를 활용하여 임계영역을 오가면서 구현이 되었지만, 멀티 쓰레딩을 지원하면서부터 Copy와 Write가 동시에 처리될 수 있게 되었다.
Process Termination
프로세스가 종료되는데는 두 가지 방식이 있다. 먼저 Voluntary Termination, 즉 자발적인 종료이다. main에서 끝나거나, exit 함수 호출 등으로 정상적으로 종료가 될 수 있다. 이런 방식으로 Process가 종료될 때 Process의 자원이 OS에 의해 Deallocate되어 가역 공간이 확보된다. 반면 Involuntary Termination, 즉 비자발적 종료 방식도 존재한다. 다른 Process나 OS에 의해 타의적으로 Process가 종료될 수 있다. Kill, Abort 등의 System Call로 Process를 종료시켜버릴 수 있다. 이렇게 종료시키는 데에는 여러 이유가 있을 수 있는데 세 가지 정도로 정리해볼 수 있겠다. 먼저 자식 Process가 불필요해질때 종료시킬 수 있다. Exec되지 않고 계속 Fork된 상태로 아무것도 하지 않거나 부모 Process와 같은 작업을 하고 있다면 이는 명백히 자원관리자라는 OS의 입장에서는 Resource가 낭비되고 있는 것이다. 또한 System Level, Logical Level, Resource Level에서 잘못을 했을 경우에 발생할 수 있다. 에러가 발생했을 때 이를 복구하지 못하는 Critical Error일 경우에는 종료시키는 것이 최선일 수 있다. 마지막으로 정책적인 이유가 있다. 여기에는 Terminal의 강제 종료, Deadlock등 여러가지 이유가 있을 수 있다. 자세한 것은 책읜 figure 3.2를 참고하면 되겠다.
Zombie
process가 Terminate하게 되면 OS가 Process의 자원을 Deallocate한다고 언급했다. 그러나 실제로 OS는 모든 자원을 Deallocate하는 것이 아니라 PCB를 제외한 Process Image들을 Deallocate하는 것이다. 즉 OS는 여전히 PCB를 가지고 있는 상태인 것이다. 하지만 OS가 이 PCB를 가지고 있더라고 종료된 Process는 다시 재실행 시킬 수는 없다. 이 PCB는 Parent Process가 Reaping할때까지 OS내에 남아있다. Reaping이라고 하는 것은 Parent Process가 Child의 Exit 정보를 가져오는 행위인데, Reaping이 일어나기 전까지 PCB가 남아있는 이 애매모호한 상태를 Zombie State라고 일컫는다. Zombie Process도 결국 System Resource를 사용하는 것이기 때문에 이를 너무 많이 생성되지 않도록 코드를 짜야한다.
Orphan
직역하면 고아라는 의미이다. Orphan Process는 Parent Process가 Child Process를 기다리지 않고 먼저 Terminate되어 Reaping 조차 일어나지 않는 상황에서 발생한다. 이런 경우에는 Child Process의 Parent를 first(init) process로 재지정한다.
Execution Options
Parent/Child Process는 Concurrently하게 수행이 된다. 즉 병렬적이고 동시에 수행이 되는 것이다. 이 때문에 누가 먼저 수행이 되는지는 오직 Scheduler 함수가 결정할 일이기에 인간의 입장에서는 Non-Deterministic하다. 그러나 대게 Parent Process는 Child Process가 끝날때까지 기다려준다. 정상적으로 Reaping이 동작하려면 이 구조가 완성되어야 하기 때문이다. Reaping하는 방법에는 wait System Call을 사용하는 방법이 있는데 이렇게 되면 Parent Process는 Block되기에 waitpid 등의 Sys Call을 사용하기도 한다.
Process가 종료될때는 Clean Up Handler가 자동적으로 호출된다. atexit같은 함수를 통해 Terminate할 때 수행할 작업을 지정가능하다. PCB는 Zombie State로 set되고 exit status(PCB 정보)는 Kernel에 전달이 된다. 이때 System Resource를 Release하고 부모 프로세스에게 Signal을 전송한다. 필요한 경우에 Orphan Process를 Reparenting해주면 된다.
이 부분에 대해서는 시스템 프로그래밍 파트에서 더 자세히 정리가 되었으니 아래의 링크를 참고하면 좋겠다.
Reference
William Stallings. (2018). Operating Systems: Internals and Design Principles (8th Edition): Pearson.
'Univ > Operating System(OS)' 카테고리의 다른 글
[OS] Process Scheduling II (Round Robin, SRT, HRRN) (0) | 2022.08.04 |
---|---|
[OS] Process Scheduling I (Intro, FIFO, SPN) (0) | 2022.08.03 |
[OS] Process Description and Control IV (Mode Switch, Context Switch) (0) | 2022.08.01 |
[OS] Process Description and Control III (Process State Models) (0) | 2022.07.30 |
[OS] Process Description and Control II(Process Description, PCB, Process Image) (0) | 2022.07.28 |