Process 란 무엇인가
What is Process
실행중인 프로그램.
Process 의 구조
다음과 같이 실행을 위한 자원들이 필요하다.
- CPU : PC , SP 같은 레지스터들
- Memory(주소 공간)의 영역들 , 낮은주소 -> 높은주소 순으로 작성
- text 영역 : 프로그램 코드들
- Data 영역 : 전역 변수들
- Heap 영역 : 동적할당 된 것들.
- Stack 영역 : 지역변수 , 매개변수 등…
- I/O 정보 : 장치를 포함한 open 된 파일들
Process API
프로그램은 어떻게 실행되는가
- Load 합니다. : 주소공간에 코드와 static data 를 넣는다.
- 동적 할당 합니다. : stack , 파라미터 초기화 , 필요하면 Heap을 사용합니다.
- 초기화
- entry point 점프
Process 의 Status & “Justice”
new
상태 : 프로세스가 이제 막 만들어진 상태 , 메모리에 올라가기 전의 상태이다.ready
상태 : 프로세스가 메모리로 올라간 상태. CPU 에 올라가기 전 상태이다.running
상태 :ready
상태에서 dispatch(스케줄 이라고도 한다) 가 되어 CPU 를 할당받아 실제 수행되고 있는 상태를 말한다. 그런데 프로세스 하나가 CPU 를 독점하는것을 방지하기 위해 timeout을 시켜 강제로 다시ready
로 돌아가게 할수도 있다. 아를 선점(preemptive) 한다라고 한다.waiting
상태 : I/O 또는 이벤트로 인해 잠시 대기 상태로 전환된 상태이다. 이벤트가 종료되면, 프로세스는 다시ready
상태로 돌아간다.terminated
상태 :running
상태인 프로그램이 종료되면terminated
상태가 된다.suspend
상태 :ready
상태 나waiting
상태인 프로세스를 메모리에서 내리는 것이다.running
상태에선 suspend 시킬수 없고 ,waiting
상태가 suspend 되면suspend-wait
상태라 한다.- resume :
suspend
상태에서 다시 메모리로 올라가는것을resume
이라 한다.
PCB(Process Control Blcok)
- 프로세스를 관리하기 위해서 하나의 자료구조가 만들어지고 거기에 프로세스의 정보가 담겨있는 것 이 생기는데 이를 PCB 라고 함.
- 프로세스의 상태 , pid,PC(Program Counter),CPU 스케줄링 정보등을 가지고 있음.
Process 관련 system call
- fork() : 새로운 프로세스를 생성. 생성된 프로세스의 ID(PID) 를 반환한다. 부모 프로세스가 먼저 호출 될 시 , 자식프로세스가 먼저 실행될 지 알수 없다. 즉 Non-deterministic 하다.
-
wait() : 자식 프로세스가 끝날 때 까지 wait 를 호출한 이후의 작업을 실행시키지 않는 system call. 즉 fork 함수를 deterministic 하게 바꿔준다. 죽은 자식 프로세스 pid 를 반환한다.
예를 들어보자 . 아래와 같은 코드가 있다.
// C program to demonstrate working of wait() #include<stdio.h> #include<stdlib.h> #include<sys/wait.h> #include<unistd.h> int main() { pid_t cpid; if (fork()== 0) exit(0); else cpid = wait(NULL); printf("Parent pid = %d\n", getpid()); printf("Child pid = %d\n", cpid); return 0; }
이코드는 무조건 아래와 같은 순서로 결과가 나오게 된다.(pid 값은 변경될 수 았음.)
- exec() : 코드와 static data를 Load 및 덮어쓰기 를 하고, stack 과 heap 을 초기화 하고 실행합니다. 사용자가 원하는 프로그램을 실행시킬 수 있습니다.
- exec 과 fork 를 분리한 이유 : 자식 프로세스 가 끝나기 전 무언가를 하고 싶을 수 있기 때문에
- getpid() : pid 를 획득
Time sharing
프로세서들이 자원을 공유할수 있도록 하는 시스템. CPU 를 시간을 작게 분할해 여러 작업을 돌아가면서 수행하는것. CPU 를 가샇와하는 핵심 테크닉.
Issues
- 성능 : 가상화 오버헤드를 어떻게 최소화 시킬것인가?
- 제어 : 중간에 인터럽트가 발생할 때마다 OS는 어떻게 제어할 것인가?
Solution
Direct Execution
운영체제를 거치지 않고 직접 수행, 효율적이지만 **컨트롤 할수 없다. 즉, 프로세스는 무한히 돌것이고, 자원을 독점해 버릴 것입니다.
이와 반대되는 개념으로 , indirect execution 이 있습니다.
Direct Execution
의 절차
- OS 에서 프로세스 리스트에 엔트리를 생성
- OS 에서 프로그램 메모리 할당
- OS 에서 메모리로 로드
- OS 에서 argc/argv 를 사용해서 스택 설정
- 프로그램에서 main 문 실행
- OS 에서 프로세스 메모리 헤제 및 프로세스 리스트에서 제거
Direct Execution Solution
Direct Execution 의 단점을 해결할 두 가지 해결방안이 있다.
- 자원과 관련된 요청이 오면 OS가 개입한다.(system call 을 통해)
- 유저모드 와 커널모드를 구분한다. 모드를 변경할떄
trap
명령을 사용한다.
trap
trap은 trap table(a.k.a IDT , Interrupt Descriptor Table )
을 사용해서 발생시킵니다.
trap table
은 trap handler
들로 구성이 됩니다. trap handler
엔 system call handlere, div_dy_zero handler,segment fault handler 등이 있습니다. 부팅 시간에 초기화 됩니다.
예를 들어, system call 의 처리 절차는 다음과 같습니다.
- 프로그램(유저모드) 에서 system call trap 을 호출합니다.
- 하드웨어 단에서 kernel stack에 register 값들을 저장하고, 커널 모드로 이동하고, trap handler로 점프합니다.
- OS 단(커널 모드)에서 trap 을 제어하고, system call 을 수행한뒤 다시 뒤돌아 갑니다.
또 다른 OS 개입 방법 - Timer interrupt and Context switch
프로세스 가 변경될 때마다 OS가 개입해야하는데, 두가지 방법이 있습니다.
- 협력적인 방법 : system call 을 발생시킵니다.
- 비협력적인 방법
- timer interrupt 사용. 사람의 심장처럼 주기적으로 timer interrupt 를 발생시키고 필요 시 스케줄링 을 진행합니다.
Context switch(문맥 교환)
: Context 저장 과 복구Context switch
의 흐름 : process A 실행 -> Process B 도입 : A의 context 를 저장하고 B의 context 를 올림 -> B 종료 -> B의 context를 저장하고 저장했었던 A의 Context 를 다시 로드.
Context switch
context switch (문맥 교환) 은 선정 되었을 떄 프로세스 의 마지막 상태를 기억합니다.
- Context save : 메모리에 이쓴ㄴ PCB 에 CPU
- Context restore : CPU register 들에 PCB 를 로딩하는 것을 말합니다.
- Switching 하는 동안은 우용한 일을 못하는 overhead 가 발생합니다.