- fork() System call: child process 생성
- 복사되는 내용
- address spcae
- register file
- PC: 형재 실행할 명령어 주소 담긴 레지스터
- code
#include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]){ printf("hello world (pid:%d) \\n", (int) getpid()); int rc = fork(); if(rc < 0){ fprintf(stderr, "fork failed\\n"); exit(1); } else if (rc == 0){ printf("hello, I am child (pid:%d)\\n", (int) getpid()); } else { printf("hello, I am parent of %d (pid:%d)\\n", rc, (int) getpid()); // rc 요놈 조심하게 !! -> rc에 child의 pid가 들어감 } return 0; }
- 복사되는 내용
- wait() System Call
- code
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/wait.h> int main(int argc, char *argv[]){ printf("hello world (pid:%d) \\n", (int) getpid()); int rc = fork(); if(rc < 0){ fprintf(stderr, "fork failed\\n"); exit(1); } else if (rc == 0){ printf("hello, I am child (pid:%d)\\n", (int) getpid()); } else { int wc = wait(NULL); printf("hello, I am parent of %d (wc:%d) (pid:%d)\\n", rc, wc, (int) getpid()); // rc 요놈 조심하게 !! -> rc에 child의 pid가 들어감 // wait 역시 마찬가지, 자식 프로세의 pid가 들어감 } return 0; }
- 가스라이팅 가능한 이유: time sharing between running processes
- process?
- program in execution
- process의 구성요소
- Memory (Address space 의미) : instruction + data section
- Registers : program counter + stack pointer + etc.
- process API
- 생성 : create
- 파괴 : destroy
- 기다려 : wait
- 잡다한 control : miscellaneous control
- 상태 : status
- process creation
- Load a program into address space
- program : 실행 가능한 형태로 disk에 있어야
- OS는 게으르게 프로그램을 주소 공간에 load; 필요한 부분만
- 프로그램의 runtime stack 할당
- 지역 변수, 함수 인자, 리턴 주소를 담을 스택을 초기화 → main의 argc, argv도 들어감
- 프로그램의 heap 생성
- OS 다른 초기화 작업 : I/O setup
- 프로그램 시작 : main()부터 시작혀
- Load a program into address space
- process 상태
- ready
- blocked
- running
- (initialized, zombie)
- 추가 자료 구조
- process list : ready process 담을 list, blocked process 담을 list, 그리고 현재 실행중인 process
- PCB : 각 프로세스의 관리할 필요가 있는 정보 담은 자료구조
- Direct Execution의 문제
- 제한된 작업 : I/O 필요할 수도 있고, CPU 더 할당받고 싶을 수 있음 → user/kernel 분리, system call
- 프로세스 간 자원 이용 위한 switching : 바보 프로세스나, 자원 계속 할당 받으려고 하는 애 → yeild(cooperative), timer interrupt(non-cooperative)
- TIMER INTERRUPT
- boot sequence 동안, OS는 timer 실행한다.
- 그 timer는 interrupt를 많은 millisecond만큼 발생시킨다.
- interrupt가 raise된다면,
- 현재 실행 중인 프로세스를 중단,
- 프로그램의 상태를 저장,
- 그리고 사전에 구성된 OS의 interrupt handler가 실행된다.
- interrupt가 raise된다면,
- TIMER INTERRUPT
- timer interrupt 시의 코드 및 과정그리고 OS는 interrupt timer를 시작한다.
- 동시에 hardware에서는 timer를 실행하고 X ms마다 CPU를 interrupt를 한다.user mode에서 process A가 실행하다가 설정한 시간보다 오래 수행하면 timer interrupt를 발생시키고, A의 kernel 스택에 레지스터 값을 저장하고, kernel 모드로 전환한다. 그리고 trap handler로 jump하게 되면 OS가 CPU를 다시 잡게 된다.OS는 trap을 처리하고, switch routine을 실행하게 된다. 다음에 실행할 프로세스를 B로 정해두었다고 치면, A의 레지스터 값들을 A의 PCB에 저장하고, PCB에서 B를 다시 불러온 다음 B의 커널 스택으로 switch를 진행한다. 그리고 B로 return-from-trap instruction을 수행한다.이제 User mode로 전환되면서 process B가 CPU를 사용하게 된다.
- 그러면 hardware에서는 kernel stack에 저장되어 있는 값들을 B의 레지스터 값으로 다시 불러오고, user mode로 바꿔주면서 B의 PC로 jump한다.
출처: https://blog.kakaocdn.net/dn/NxcpO/btr7hSIqDrq/KE3xWYx0KE6FCf8kCInQwk/img.png 출처: https://blog.kakaocdn.net/dn/bCeAoe/btr7CUR5akS/bF7egaW99wQdikenNdRhYk/img.png - OS는 부팅하면서 trap table을 초기화 한다. 그리고 hardware에서는 syscall handler와 timer handler의 주소를 기억해둔다.
- imited Direct Execution Protocol (Timer interrupt; for context switching)
- scheule : 스케줄러가 프로세스 판단
- context switch
- 매우 적은 register values만 저장
- General 한 목적의 register
- PC
- kernel stack의 pointer
- Restore a few soon-to-be executing process form its kernel stack
- Switch to the kernel stack
- 매우 적은 register values만 저장
- Concurrency Issue
- concurrency issue 때 trap 발생하면 어케 돼? → interrupt 중첩
반응형
'OS' 카테고리의 다른 글
[운영체제] 4. Advanced Scheduling Schemes (0) | 2024.03.25 |
---|---|
[운영체제] 3. Scheduling Basics (0) | 2024.03.25 |
[운영체제] 1. What is an OS? (0) | 2024.03.25 |
Swap Space의 상호작용- (Physical Memory, Present Bit, Page Frame, Memory) (0) | 2023.04.06 |
Memory Management Policy (0) | 2023.04.06 |