Overhead : 어떤 처리를 하기 위해 들어가는 간접적읜 처리 시간 • 메모리 등을 말함
Table 3.8은 OS를 제어할 수 잇는 가능한 이벤트를 제시한다.
Mechanism
Cause
Use
Interrupt
현재 명령어의 실행에서 외부적 요인
asynchronous(비동기적) 외부 이벤트로 반응
Trap
현재 명령어의 실행과 연관된 요인
error 또는 exception 조건 처리
Supervisor call
Explicit request(명시적 요청)
operating system function을 호출
Asynchronous(비동기적) : 동시에 똑같이 진행되지 않는다. <=> Synchronouse(동기적)
프로그램이 system call을 실행하거나 exception을 트리거했을 경우
kernel은 "프로세스를 대신하여 실행"한다고 한다.
kernel이 process context 안에 있다.
Interrupt handler 실행 시
어떠한 프로세스와도 관련되지 않음
kernel은 interrupt context에 있음(많은 OS에서)
Interrupt handler는 다른 코드를 interrrupt한다. → 빠르고 간단해야 한다.
interrupt context는 절전 모드(sleep)로 전환할 수 없다.(reschedule을 어떻게 해?)
ex. in_interrupt()가 true를 반환하면, kernel은 interrupt context에 있다.
Process context: 커널 동작 상태 중 하나로, system call을 하거나 커널 스레드를 실행할 때와 같이 프로세스 대신에 커널이 실행되는 상태 Interrupt context : 프로세스 컨텍스트와 비슷하지만, 인터럽트 컨텍스트는 위와는 달리 특정 프로세스와 묶여 있지 않음
각 프로세서는 주어진 순간에 정확히 세 가지 작업 중 하나를 수행한다.
user-space, 프로세스에서 user code를 실행한다.
kernel-space, process context에서 특정 프로세스 대신 실행
kernel-space, interrupt context에서 프로세스와 연관되지 않은 interrupt를 처리
mode switch는 현재 running state에 있는 프로세스 상태를 변경하지 않고 발생할 수 있다.
mode switch 후 kernel은 다양한 이유로 process switch를 시작할 수 있다.
3. Execution Model of OS
mode switch만 현재 실행중인 프로세스의 상태를 변경하지 않는다.
1) Execution within User Processes (OS에서 공통)
이 접근 방식의 주요 이점
현재 user process 내에서 실행이 계속된다. 따라서 process switch가 수행되지 않고 동일한 프로세스 내의 mode switch만 수행된다.
현재 프로세스의 context에서 모든 OS 기능을 실행
각 process image는 커널용 프로그램, 데이터 및 스택을 포함한다.
프로세스가 커널 모드에 있는 동안 별도의 kernel stack이 사용된다. → 프로세스 내에서 두 개의 스택이 필요(kernal stack, user stack)
각 process image에는 커널 프로그램을 위한 코드, 데이터 및 스택 영역만 포함된다.
커널 스택은 프로세스가 커널 모드에 있는 동안 call/return을 관리하는 데 사용된다.
커널 텍스트와 데이터는 모든 사용자 프로세스에 공유될 수 있다.
각 프로세스는 두 개의 스택을 가진다
User space stack
user code에서 사용됨
Kernel space stack
kernel code에서 사용됨(예. system call 중)
Advantage
user stack이 손상된 경우에도 kernel을 실행할 수 있다.
4) Process Switch
1) When to Switch Processes
Process Switch
프로세서를 한 프로세스에서 다른 프로세스로 전환
mode switch 후 커널은 다양한 이유로 process switch를 시작할 수 있다.
Interrupt
모든 해당 blocked process를 ready state로 이동하는 OS는 현재 running state에 있는 프로세스의 실행을 다시 시작할 지 아니면 우선 순위가 높은 ready process를 선점(preempt)할지 결정해야 한다.
예를 들어, OS는 timer interrupt를 통해 현재 실행 중인 프로세스가 time slice에 대해 실행되었는지 여부를 확인한다.
Exception
OS는 error 또는 exception condition이 치명적인지 여부를 결정
치명적이라면 현재 실행 중인 프로세스가 exit 상태로 이동하고 process switch가 발생
System Call
system call을 사용하면 user process가 blocked state가 될 수 있다.
2) Process Switch
mode switch보다 더 많은 노력이 필요함
현재 프로세스의 processor context를 저장한다.
현재 프로세스의 PCB 업데이트(Ready, Blocked, Exit)
Ready : timer interrupt로 인해 process switch가 생길 경우
Blocked : I/O device에 의해 발생할 경우
Exit : exception에 의해 발생할 경우
이 프로세스의 PCB를 적절한 Queue로 이동한다.
실행할 다른 프로세스 선택(9장에서 call schedule() )
선택한 프로세스의 PCB 업데이트(Running)
선택한 프로세스의 processor context 복원
3) Schedule Function
Schedule function(Selection function)
ready process 중에서 실행을 위해 다음에 선택할 프로세스를 결정
fucntion은 우선순위 또는 프로세스의 실행 특성에 기초할 수 있다.
예 : Linux의 CFS(완전 공정 스케줄링)
4) An Example : Process Switch
Scenario(시나리오) : P는 yield()를 호출하여 자체 process switch를 일으킨다.
yield() system call : CPU 자발적 context swtich를 포기한다.
(1) 1단계
P는 yield call instruction을 실행할 것이다.
(2) 2단계
P는 System call request를 실행한다 : int 0x80
mov 7, $eax : system call 번호 지정
(3) 3단계
커널에서 sys_yield 로 jump한다.
PC : system call table의 전용 함수 sys_xxx()
SP : kernel stack을 설정 및 kernal stack의 맨 위
kernal stack에 user mode였을 때 PC, SP를 저장함
(4) 4단계
Scheduling은 process swtiching 메커니즘에 의해 시행된다.
setting old와 new는 건너뛴다.
old : current process P / new : switch Q의 다음 프로세스
(5) 5단계
process_switch() 함수를 가정해라
in_progrss를 0으로 초기화
save_context(old); : P의 PCB의 현재 하드웨어 정보를 저장
restore_context(new) : Q의 PCB의 정보를 restore해서 하드웨어에 setting
(6) 6단계
현재 프로세스 P의 context를 P의 PCB에 저장(교재로 치면 processor state infomation field에 저장)
저장과 동시에 PC는 return instruction인 save_context()의 끝 가리킨다.\
save_context()의 끝인 PC 값을 저장하였으므로 P 프로세서가 restore되면 해당 값이 PC로 restore 되어서 진행됨
(7) 7단계
in_progess를 체크, 0이다
(8) 8단계
in_progress를 1로 set
(9) 9단계
또 다른 processs의 context를 PCB(Q)에서 restore한다.
이제 프로세스 Q에 대한 시간이다.
(10) 10단계
결국에는 다른 프로세스가 restore_context()를 수행하면 프로세스 P로 다시 전환된다.
(11) 11단계
PCB에서 컨텍스트를 로드하여 프로세스 P를 재개한다.
Recall : PC가 return form save_context였고, 그래서 process_switch()로 돌아간다.
(12) 12단계
in_process를 확인, 1이다.
(13) 13단계
sys_yield process P로 다시 돌아온다.
더이상 PCB context가 필요하지 않다(그래서 다음에서 그것들을 숨긴다.)
(14) 14단계
CPU를 user mode로 reset
스택에서 return address를 팝한다.
5. Process Creation
1) Process creation( Directed )
새 메모리 공간 할당
a.out 및 PCB에 메모리 할당
새 메모리 공간에 a.out을 로드한다.
코드 및 데이터를 메모리에 로드
call stack 만들기
PCB 초기화
PCB 작성 및 시작
새로운 프로세스 시작
프로세스를 read-list에 추가(적절한 linkage 설정)
예제) the first process(Super parent)
/sbin/init ( in UNIX) : 다른 것들과 달리 이것은 부팅 중에 커널에 의해 생성됨
다른 모든 프로세스의 forking 하는 역할
(1) Prccess Createion 원인
원인
설명
New batch job
OS에는 일반적으로 tape 또는 disk에 bath job control stream을 제공된다. OS가 새로운 작업을 수행할 준비가 되면 job control command의 다음 시퀀스를 읽는다.
Interactive log-on
터미널의 사용자가 시스템에 log on한다.
Created by OS to provide a service
OS는 사용자가 기다릴 필요 없이 사용자 프로그램을 대신하여 기능을 수행하는 프로세스를 만들 수 있다.(예: 인쇄 제어 프로세스)
Spawned by existing process (기존 프로세스에 의해 생성된)
parallelism(병렬화)를 활용하기 위한 modularity(모듈화)를 위해 사용자 프로그램은 여러 프로세스를 생성하도록 지시할 수 있다.
2) Process Creation (by Cloning)
(1) Cloning
Child 프로세스는 parent의 exact replica(정확한 복제본)이다.
유사한 environment variables(환경 변수) ex. bash -ps
fork() system call ( "Process Spawning"이라고 불림)
text, data, stack 및 PCB 복사본 만들기
pid, relation 수정
read-list에 새로운 PCB 추가
(2) Replacing
Process Identifier(PID, 프로세스 식별자)는 변경되지 않지만 machine code, data, heap 그리고 stack은 새 프로그램의 것으로 대체된다.
execve() system call
fork() : 현재 프로세스에서 다른 프로세스를 만든다. 현재 프로세스를 부모 프로세스라고 하고 만들어진 새로운 프로세스를 자식 프로세스라고 한다. fork가 리턴하는 값 pid_t가 0 이면 자식 프로세스 0보다 크면 부모 프로세스임을 알 수 있다. - 두 프로세스의 변수 값, PC,값은 정확히 똑같고, pid값만 유일하게 달라짐 exec family : 현재 실행되는 프로세스에서 다른 프로세스 일을 하게 하는 것
(3) Cloning 예시
Hello의 경우 부모 프로세스에서만 실행
Bye의 경우 자식, 부모 프로세스 모두에서 실행
pid > 0 이 참이면 부모 프로세스, pid = 0면 자식 프로세스이다.
3) Why? Motivating the API
UNIX shell을 구축하려면 fork()와 exec()의 분리가 필수
4) Copy on Write(COW)
처음에 공유로 표시된 모든 parent page
공유 page의 데이터가 변경되면 OS가 page의 복사본을 만듦
따라서 부모와 자식이 변경된 페이지의 복사본이 서로 다름
다른 모든 page는 동일하게 유지
(1) Example in Linux
자식 프로세스는 execl을 만나서 다음 코드부터 수행되지 않음
부모 프로세스는 자식 프로세스가 execl을 만나면 wait 상태에서 빠져나와 코드를 진행
6. Process Termination
Voluntary termination(자발적 종료) : exit(status)
main routine에서 return
exit function 호출
프로세스 종료 결과
하위에서 상위로 데이터 출력(wait() 통해서)
프로세스의 리소스가 OS에 의해 할당 해제됨
Involuntary termination(비자발적 종료)
다른 프로세스(부모) 또는 OS에 의해
kill(pid, signal) 또는 abort()
기본 action이 종료되는 signal 수신
예 : SIGTERM, SIGINT(ctrl+C).
7. Zombie Process
1) Zombie( Unix-like OS)
(1) Zombie
exit()에 의해 프로세스가 종료될 때 커널은 시스템에서 PCB를 즉시 제거하지 않음
프로그램이 더 이상 실행되지 않음에도 불구하고 OS에 PCB가 여전히 존재
Linux에서는 종료된 프로세스에 대한 task_struct가 여전히 존재하지만 실행할 수 없음
대신 프로세스는 상위 프로세스에 의해 reaping될 때 까지 terminated state로 유지된다.
이를 "Zombie state"라고 부름
시스템 내 Zombie 프로세스 수가 계속 누적되고 사라지지 않을 때 문제 발생
(2) Reaping
exit status는 부모 프로세스로 전달된다.
그런 다음 커널이 zombie child process를 삭제한다.
parent에 의해 수행(wait을 사용하여)
(3) 예시
background에서 ps -a 명령어 실행
상위 프로세스가 wait()을 호출하거나 종료될 때까지 zombie state로 있는다.
2) Execution options
상위 및 하위가 동시에 실행된다.
상위 프로세스는 하위 프로세스들이 종료될 때까지 wait한다.(Reaping)
부모 프로세스는 wait() system call을 사용하여 자식 프로세스가 종료될 때까지 기다릴 수 있다.
call은 종료된 프로세스의 status 정보와 pid를 반환한다.
pid = wait(&status);
pid = waitpid(-1, &status, WNOHANG)
3) Orphan (Unix-like OS)
(1) Orphan
상위 프로세스가 하위 프로세스보다 먼저 종료될 경우
첫번째 프로세스에 의해 채택됨(/sbin/init)
(2) Process Termination
cleanup handler가 자동으로 호출된다.
ZOMBIE 상태와 커널 구조에 저장된 exit status로 설정
이 프로세스가 보유한 시스템 리소스를 해제한다.
task의 상위로 signal 전송
task의 orphaned children을 init process에 다시 reparent