선점형 스케쥴러
하나의 프로세스가 다른 프로세스 대신에 프로세서(cpu)를 차지할 수 있다!
어떤 프로세스가 running 중에 스케쥴러가 이를 중단시키고, 다른 프로세스로 교체가능!
비선점형 스케쥴러
하나의 프로세스가 끝나지 않으면 다른 프로세스는 cpu 사용할 수 없음…
자발적으로 wait으로 되거나, 혹은 실행이 끝났을 때만 다른 프로세스로 교체 가능!
즉 cpu가 임의로 실행 중인 프로세스를 종료시키지 못한다.
===
인터럽트
cpu는 명령 하나하나 실행 중일때, 다른 장치와 어떻게 커뮤니케이션 할까?
cpu가 프로그램을 실행 중 일때, 장치, 혹은 예외 상황이 발생해 처리가 필요할 경우 cpu에 알려서 처리하는 기술.
인터럽트는 특정 프로세스의 코드가 아닌 일종의 이벤트.
이벤트에 맞게 운영체제가 처리한다!
인터럽터 필요 이유
선점형 스케쥴러 구현
- 어떤 프로세스가 running 중에 이를 중단시킬 때, 인터럽터가 필요.
IO 디바이스와 커뮤니케이션
- 저장매체에서 처리 완료 시, 프로세스를 깨워야 함(block -> ready)
예외 상황 핸들링
- 어떤 문제가 생겼을 때, cpu에서 이를 처리할 수 있도록 cpu에 알려줘야 함
인터럽트 종류
1. 0으로 나누는 코드 실행 시 (Divide by Zero Interrupt)
1 | int main(){ |
이런 시도를 하게 되면, 운영체제가 해당 프로세스를 종료시키고, 인터럽트를 발생시킨다!
2. 타이머 인터럽트
- 선점형 스케쥴러를 위해 필요.
하드웨어로부터 일정 시간마다 타이머 인터럽트를 운영체제에 알려준다!
cpu가 다른 프로세스를 실행 중이라 바쁠 때, 특정 시간마다 인터럽트를 일으켜 알려준다!
3. 입출력 인터럽트
- 프린터, 키보드, 마우스….
인터럽트 종류
내부 인터럽트(소프트웨어 인터럽트)
- 주로 프로그램 내부에서 잘못된 명령 또는 잘못된 데이터 사용시 발생.
- 0으로 나누거나, 사용자 모드에서 허용하지않는 명령 실행, overflow, underflow…
외부 인터럽트(하드웨어 인터럽트)
- 주로 하드웨어에서 발생되는 이벤트(프로그램 외부)
- 전원 이상, IO 관련 이벤트, Timer이벤트…
===
인터럽트 내부 동작 구조
시스템 콜 인터럽트
- 시스템 콜은 인터럽트를 활용해야 함.
- 시스템콜 실행을 위해서는 강제로 코드에 인터럽트 명령을 넣어 cpu에 실행 시켜야 함
- 기계어로 컴파일 될 때 시스템 콜 코드가 삽입된다.
1
2
3mov eax, 1 //eax레지스터에 시스템콜 번호 넣고
mov ebx, 0 //ebx레지스터에는 시스템 콜에 해당하는 인자값 넣고
int 0x80 //소프트웨어 인터럽트 명령 호출하면서 0x80값 넘겨준다.
시스템콜 인터럽트 명령이 호출되면서 0x80값을 넘겨주고,
cpu는 사용자모드에서 커널 모드로 전환
IDT(Interrupt Descriptor Table)에서 0x80에 해당하는 주소(함수)를 찾아서 실행
- 인터럽트 번호에 맞는 주소(코드)를 적어놓은 테이블 ex) 0x80 : system.call()
찾은 system_call() 함수에서 eax로부터 시스템 콜 번호를 찾아서, 해당 번호에 맞는 시스템콜 함수로 이동
- system_call()에서 시스템 콜 번호에 따라 매칭 되는 함수를 찾아서 실행 시킴
- system_call()에서 시스템 콜 번호에 따라 매칭 되는 함수를 찾아서 실행 시킴
해당 시스템 콜 실행 후, 다시 커널 모드를 사용자 모드로 전환, 해당 프로세스의 다음 코드 진행.
인터럽트와 IDT
인터럽트는 미리 정의되어 각 번호와 실행 코드를 가리키는 주소가 기록되어 있다.
- where? : IDT(Interrupt Descriptor Table)에 기록해 놨다.
- when? : 컴퓨터 부팅시 운영체제가 기록한다.
- what? : 운영체제의 내부 코드를 기록한다.
인터럽트와 프로세스의 관계
- 프로세스 실행 중 인터럽트 발생
- 현 프로세스 실행 중단
- 인터럽트 처리 함수 실행(운영체제)
- 현 프로세스 재실행