[3주차] - 프로세스 관리
프로그램의 실행
- 사용자 프로그램들은 실행시킬 때 메모리에 적재된다(가상메모리를 거친다).
- 프로그램이 실행될 때는 프로그램만의 독자적인 주소공간이 생기는데 이를 가상메모리라고 한다.
- 각각의 Address Space에는 stack, data, code으로 구성되어 있다.
- code에는 실행파일에 있던 코드가 적재되는 부분으로 실제 CPU에서 실행할 기계어가 있다.
- data는 데이터가 적재되어 있는 부분이다.(모든 데이터가 아닌 전역변수, 프로그램의 생명주기와 함께하는 데이터가 존재한다)
- stack에는 함수의 호출과 리턴에 관련된 정보들이 저장되어있다.
커널 주소 공간의 내용
- 커널 코드
- 시스템 콜, 인터럽트 처리 코드
- 자원 관리를 위한 코드
- 편리한 서비스 제공을 위한 코드
사용자 프로그램이 사용하는 함수
- 함수(funtion)
- 사용자 정의 함수
- 라이브러리 함수
- 자신의 프로그램에서 정의하지 않고 갖다 쓴 함수
- 자신의 프로그램의 실행 파일에 포함되어 있다
- 커널 함수
- 운영체제 프로그램의 함수
- 커널 함수의 호출 = 시스템 콜
프로그램의 실행 과정
- 유저모드와 커널모드는 modeBit에 따라 결정된다.
프로세스의 개념
- 프로세스는 실행중인 프로그램!
- 핵심은 문맥(context)이다.
- 프로세스의 현재 상태가 문맥이다.
- 하드웨어 문맥
- Program Counter(어느 부분을 수행하고 있었는가?)
- 각종 레지스터
- 프로세스의 주소 공간
- 프로세스 관련 커널 자료 구조
- PCB(Process Control Block)
- Kernel stack
프로세스의 상태
- CPU는 하나이기 때문에 매 순간 기계어를 실행하는 프로세스는 하나이다.
- 프로세스는 상태(state)가 변경되며 수행된다
- Running
- Ready
- CPU를 기다리는 상태(메모리 등 다른 조건을 모두 만족하고)
- Blocked(wait, sleep)
- CPU를 주어도 당장 명령어를 수행할 수 없는 상태
- Process 자신이 요청한 event(예: I/O)가 죽시 만족되지 않아 이를 기다리는 상태
- 디스크에서 file을 읽어와야 하는 경우
프로세스 상태도
- New : 프로세스가 생성중인 상태(생성이 안되었으면 프로세스가 아니므로)
- Terminated : 수행이 끝난 상태
- ready
- 프로세스가 메모리에 올라간 상태
- CPU만 보유하면 바로 명령어를 실행할 수 있지만 CPU를 할당받지 못한 상태
- running
- CPU를 갖고 명령어를 수행중인 상태
- 3가지 경우를 통해 CPU를 반납함
- blocked
- I/O등의 event를 (스스로) 기다리는 상태
- Suspended(stopped)
- 외부적인 이유로 프로세스의 수행이 정지된 상태
- 프로세스는 통째로 디스크에 swap out 된다
- 예) 사용자가 프로그램을 일시 정지시킨 경우 시스템이 여러 이유로 프로그램을 잠시 중단시킴
- blocked와 suspended의 공통점은 둘 다 CPU를 얻지 못한다는 점
- 차이점은 suspended를 제외한 나머지 상태는 프로세스가 정지된 것이 아니라 계속 수행되는 것
Process Control Block(PCB)
- 운영체제가 각 프로세스를 관리하기 위해 프로세스마다 유지하는 정보(자료구조 형태)
- 하나의 프로세스당 하나의 PCB가 매칭된다.
- 우선순위를 관리해서 우선순위가 더 높은 프로세스에게 CPU우선권을 주는 스케줄링에 도움을 줌.
- PCB는 운영체제 커널에 존재한다.
문맥 교환(Context Switch)
- CPU가 한 프로세스에서 다른 프로세스로 넘겨주는 과정
- 문맥교환 과정에서 운영체제는 각 PCB에 프로그램 상태를 저장하고 불러오는 작업을 수행
- 문맥교환이란 사용자 프로세스A에서 사용자 프로세스B로 CPU 제어권이 넘어가는 것을 뜻함
- 문맥교환이 아닌 경우
- 사용자 프로세스A -> ISR or System call 함수 -> 사용자 프로세스 A(프로세스가 동일하다)
- 문맥교환인 경우
- 사용자 프로세스A -> ISR or System call 함수 -> 사용자 프로세스 B(프로세스 변경)
- ISR(Interrupt Service Routine) : 인터럽트 접수에 의해 발생되는 인터럽트에 대응하여 특정 기능을 처리하는 기계어 코드 루틴
- 문맥교환이 아닌 경우에도 오버헤드가 있지만 문맥교환인 경우에 오버헤드가 훨씬 크다.
프로세스를 스케줄링하기 위한 큐
- Job queue
- Ready queue
- 현재 메모리 내에 있으면서 CPU를 잡아서 실행되기를 기다리는 프로세스의 집합
- Device queues
- I/O device의 처리를 기다리는 프로세스의 집합
- 프로세스들은 각 큐들을 오가며 수행된다
프로세스 스케줄링 큐의 모습
스케줄러
- 본 강의에서는 운영체제에서 스케줄링을 하는 코드를 스케줄러라고 칭함
- 장기스케줄러는 메모리 스케줄러이다
- 단기스케줄러는 타이머 인터럽트가 발생할때마다 호출되며 매우 자주 호출된다
- time sharing system에는 보통 장기 스케줄러가 없다(무조건 ready)
- 중기스케줄러는 여유 공간을 위해 특정 프로세스를 통째로 메모리에서 디스크로 쫒아낸다
더 적합한 프로세스 상태도
스레드(Thread)
- CPU 스케줄러가 CPU에 전달하는 일 하나를 스레드라고 하며, 하나의 프로세스에는 여러개의 스레드가 존재하기도 한다
- lightweight prcess(경량 프로세스)라고 불리기도 한다
- Thread가 동료 thread와 공유하는 부분(task) - 바이너리로 되어있음
- code section
- data section
- OS resources
- 다중 스레드로 구성된 태스크 구조에서는 하나의 서버스레드가 blocked 상태인 동안에도 동일한 태스크 내의 다른 스레드가 실행되어 빠른 처리를 할 수 있다
- 동일한 일을 수행하는 다중 스레드가 협력하여 높은 처리율과 성능 향상을 얻을 수 있다
- 스레드를 사용하면 병렬성을 높일 수 있다
스레드의 구현
- 커널에 의해 지원된다면 커널스레드 (운영체제가 스레드를 앎)
- Windows 95/98/NT
- Solaris
- Digital UNIX, Mach
- 라이브러리에 의해 지원된다면 유저스레드 (운영체제가 스레드를 모름)
- POSIX Pthreads
- Mach C-threads
- Solaris threads
프로세스 생성
- 부모프로세스가 자식프로세스를 만들고 자식프로세스는 복제생성되기 때문에 부모프로세스와 똑같은 상태이다
- 프로세스의 계층 구조(트리) 형성
- 주소 공간(Address Space)
- 자식은 부모의 공간을 복사함
- 자식은 그 공간에 새로운 프로그램을 올림
- 유닉스의 예
- fork() 시스템 콜이 새로운 프로세스를 생성
- fork 다음에 이어지는 exec() 시스템 콜을 통해 새로운 프로그램을 메모리에 올림
## 프로세스 종료
- 종료되면 모든 자원을 운영체제에게 반납한다
- 프로세스는 자식이 먼저 죽고 부모가 후처리를 진행한다
- abort는 부모프로세스가 자식의 수행을 강제로 종료시키는 것이다
fork() 시스템 콜
- 실행중인 프로세스로부터 새로운 프로세스를 복사하는 함수이다.
exec() 시스템 콜
- 기존의 프로세스를 새로운 프로세스로 전환하는 함수이다.
본 포스팅은 반효경 교수님의 2017 운영체제 강의를 바탕으로 제작되었습니다.