프로세스와 프로세스 관리
· 프로그램
- 하드 디스크나 USB와 같은 저장 장치에 저장된 실행 가능한 파일
· 프로세스
- 프로그램이 메모리에 적재되어 실행 중인 프로그램
· 프로세서
- CPU, GPU와 같은 하드웨어 처리기
· 프로세스 주소 공간
- 코드 / 데이터 / 힙 / 스택
- 코드 영역: 프로세스 코드 적재
- 데이터 영역: 전역 변수(static 또는 global) 적재
- 힙 영역: malloc()으로 동적 할당받는 영역
- 스택 영역: 함수의 지역 변수, 함수의 매개변수, 함수 복귀 주소
· 가상 공간
- 사실 프로세스 주소 공간으로 나눈 코드, 데이터, 힙, 스택 영역 순서는 실제 메모리와 다름 ~ 이는 이해하기 쉽도록 구현한 가상 공간(매핑 테이블)
· 매핑
- 실제 프로세스의 주소 공간은 가상 공간이므로 매핑 테이블로 물리 주소 공간(실제 주소)에 매핑
· 가상 주소
- 프로그램에서 사용한 변수의 번지나 코드의 번지와 같이 독립적으로 메모리에 적재된 프로세스 주소들은 가상 주소
· 물리 주소(=실제 주소)
- 실제 메모리에는 데이터, 코드, 힙, 스택 또는 스택, 데이터, 코드, 힙의 순서와 같은 식으로 우리가 알고 있는 가상 주소와는 다르게 배치되어 있음
· 프로세스 테이블
- 컴퓨터가 부팅하면 시스템의 커널 공간에 프로세스 테이블이 하나가 생김, 연결 리스트 형태로 pid, pcb를 가리키는 연결 리스트와 같이 연결함 / 즉 시스템 내의 프로세스 테이블은 1개 존재하며 프로세스가 생성될 때 마다 PCB가 1개씩 생김(여러 개 있을 수 있다는 뜻)
· 프로세스 제어 블록(PCB)
- pid(프로세스의 id), ppid(부모 프로세스의 id), 프로세스 상태 정보(new, ready, running, blocked, terminated/zombie), 컨텍스트 정보(레지스터들의 값), 스케줄링 정보, 종료 코드 등이 담겨 있는 일종의 호적
- 프로세스가 생성될 때 마다 하나씩 생성되고 프로세스 테이블에 pid에 의해서 연결 리스트 형태로 연결 / Running -> Terminated, 즉 프로세스가 종료하면 할당 받았던 모든 자원을 시스템에게 반환하는데 프로세스 테이블에서 연결리스트는 끊기지 않고 Terminated/Zombie 상태가 된다. 부모가 꼭 자식 프로세스의 종료를 wait(스레드의 경우 join)을 해야만 zombie가 아니라 terminated/out 상태로 PCB까지 제거된다.
· 프로세스 및 스레드 상태(zombie가 있냐 없냐만 차이있음)
- Ready: 대기 상태
- Running: 실행 중 상태
- Blocked: 일시정지 상태
- Terminated: 종료 상태
· 종료코드(exit code): 0~255까지
- 0이 정상 종료 코드 / 1~255까지는 비정상 종료 코드
- 범위 초과한 경우: exit(-1) = 255 / exit(300) = exit(300-256) = exit(44)
· MMU(Memory Management Unit: 메모리 관리 장치)
- CPU 안에 있으면서 가상 주소를 실제 메모리 주소로 변환해주는 장치
· 프로세스 생명 주기
· Ready
- Ready > Running: 스케줄링될 때(디스패치 = 컨텍스트 스위칭)
- Running > Ready: 타임 슬라이스 경과, CPU 사용 양보(yield)
· Blocked
- Running > Blocked: I/O 요청, 잠자기 요청(sleep()), 자원 요청
- Blocked > Blocked: I/O 완료, 잠자기 타임아웃, 자원 획득
· Terminated
- Running > Terminated: 스레드 또는 프로세스 종료
· Zombie
- 자식이 죽는 것을 부모가 기다리지 않는데 갑자기 자식이 죽은 상태(wait을 안 한 경우 ~ 개발자의 부주의, 초보 개발자의 실수)
· 부모 프로세스
- 부모 프로세스가 fork()로 자식 프로세스를 100% 똑같은 모양으로 생성(똑같은 모양이란 코드, 데이터, 힙, 스택 영역에 들어있는 모든 값이 동일하다는 것임)
- exec(): 동일한 프로그램이 아니라 다른 프로그램을 실행시키고 싶을 때 부모 프로세스가 fork()로 자식 프로세스를 만들고 exec()로 새로운 프로그램을 덮어써서 실행시킴
· 자식 프로세스(fork()로 생성 시 무조건 pid = 0)
- 모든 프로세스는 부모-자식 관계로 이루어진 계층 구조이며, 프로세스는 부모의 프로세스에 의해서만 생성(fork 또는 fork 후 exec)된다.
· idle 프로세스(swapper 프로세스, #0 프로세스) = CPU가 쉬고 있는 유휴 프로세스
- 모든 프로세스가 blocked 상태여서 시스템에 실행시킬 ready 상태의 프로세스가 한 개도 없는 상황에 빠지지 않도록 하기 위해 idle 프로세스가 존재(즉, 스케줄링을 대기하고 있는 프로세스가 하나도 없으면 idle 프로세스가 실행)
· init 프로세스 / #1 프로세스
- 사용자 모드에서 실행되는 모든 프로세스의 조상
· kthreadd / #2 프로세스
- 커널 공간에서 커널 모드로 실행되면서 커널의 기능을 돕는 프로세스
· 고아 프로세스
- 좀비와는 다르게 부모 프로세스가 오류나 시스템 충돌로 인해서 먼저 종료된 경우 자식 프로세스를 고아 프로세스라고 하며, #1 프로세스인 init 프로세스가 새로운 부모가 된다(입양된다라고 표현), 새 부모가 생겼지만 여전히 고아 프로세스라고 부르긴 한다.
· 백그라운드 프로세스(눈에 안보이는 상태로 실행되는 프로세스)
- 사용자와의 대화를 필요로 하지 않는 프로세스
· 포그라운드 프로세스(UI로 우리 눈에 보이는 상태로 실행되는 프로세스)
- 터미널 사용자로부터의 입출력을 독점하는 프로세스
· CPU 집중 프로세스
- 인공지능, 이미지 처리, 행렬 연산 등 프로세스 작업 대부분이 CPU가 많은 부분 활용될 때 ‘CPU 집중 프로세스’라고 함
· I/O 집중 프로세스
- 파일을 읽고 쓰는 등 프로세스 작업 대부분이 CPU가 많은 부분 활용될 때 ‘I/O 집중 프로세스’라고 함(ex: 파일 서버)
· 프로세스 오버레이
- 부모가 fork()를 해서 자식 프로세스를 생성하고 exec()로 파일을 덮어쓰는 방식을 기억하자.
- 자식 프로세스가 exec()를 하면 현재 실행중인 프로세스의 주소 공간(코드, 데이터, 힙, 스택 영역)에 새로운 응용프로그램을 적재하여 실행시키는 기법을 프로세스 오버레이라고 함
'Development' 카테고리의 다른 글
[OS] Types of Operating Systems (0) | 2023.10.20 |
---|---|
[OS] 임계 구역 문제(The Critical-Section Problem) (0) | 2023.10.19 |
[OS] 컴퓨터 시스템과 운영체제 (0) | 2023.10.17 |
[OS] 운영체제의 시작과 발전 (1) | 2023.10.16 |
[Development] 메소드 오버로딩과 메소드 오버라이딩 (1) | 2023.10.05 |