컴퓨터 시스템 구조
- 내부장치(CPU, 메모리)
- 외부장치(디스크, 키보드, 마우스, 모니터, 네트워크 장비 등), 입출력 장치라고도 함
업무처리 방식
외부장치에서 내부장치 데이터를 읽어와 각종 연산 수행하고 내부장치에서 외부장치로 결과를 출력하는 것
입출력(Input-Output; I/O)
- 입력(input) : 외부장치에서 내부장치 데이터가 들어오는 것
- 출력(output) : 컴퓨터 외부장치로 테이터가 나가는 것
컨트롤러 : 각 하드웨어 장치마다 존제하는 일종의 작은 CPU로 장치를 제어하는 역할
커널
- 운영체제 중 항상 메모리에 올라가 있는 부분, 핵심적인 부분에 한정됨
- 운영체제는 컴퓨터가 부팅될 떄 항상 수행하며 자원들을 관리하는데, 운영체제의 모든 코드를 올리면 메모리 낭비이기 때문에 커널부분만 올려둠
메인 CPU가 담당하는 컴퓨터 내에서 수행되는 연산과 입출력 컨트롤러가 담당하는 입출력장치의 I/O연산은 동시 수행이 가능
로컬버퍼(local buffer) : 각 장치별로 제어를 위해 설치된 장비 컨트롤러에 들어오고 나가는 데이터를 임시로 저장하기 위한 작은 메모리
- 외부장치에서 데이터를 읽어 올 때, 컨트롤러가 로컬버퍼에 데이터 임시 저장 후 전송을 담당
- 로컬버퍼에 읽어오는 작업의 완료 여부는 컨트롤러가 CPU에게 인터럽트를 발생시켜 보고
인터럽트 : 컨트롤러들이 CPU의 서비스가 필요할 때 통보하는 방법
- CPU는 매 시점 메모리에서 명령(instruction)을 하나씩 읽어와서 수행하는데, CPU옆에 인터럽트라인(interrupt line)이 있어 명령을 하나 수행할 때마다 인터럽트 발생여부를 확인한다.
운영체제가 해야 할 일들을 미리 프로그래밍 하여 커널 내에 포함시켜두는데, 그 중 한 가지가 인터럽트 처리루틴이다.
인터럽트 처리루틴 : 다양한 인터럽트에 대해 각각 처리해야 할 업무들을 정의해둔 루틴들을 말함. 컨트롤러가 인터럽트를 발생시키면 CPU는 하던 일을 잠시 멈추고 인터럽트에 맞는 루틴을 찾아 코드를 실행함.
CPU의 서비스가 필요한 경우, CPU 옆에 있는 인터럽트 라인에 신호를 보내서 인터럽트가 발생했음을 알리는 방식은 동일
- 하드웨어 인터럽트 : 컨트롤러 등 하드웨어 장치가 CPU의 인터럽트 라인을 세팅
- 소프트웨어 인터럽트 : 트랩(trap)이라고도 하며, 소프트웨어가 CPU의 인터럽트 라인을 세팅
인터럽트 백터(interrupt vector) : 인터럽트 종류마다 번호를 정해 그에 따라 코드가 위치한 부분을 가리키는 자료구조
인터럽트 처리루틴(interrupt service routine) : 인터럽트 핸들러(interrupt handler)라고도 하며 인터럽트 발생 시 실제 처리해야 할 코드
소프트웨어 인터럽트의 예
- 예외상황(exception) : 비정상적인 작업을 시도하건, 권한이 없는 작업을 시도할 때 이에 대한 처리를 위해 발생시키는 인터럽트
- 시스템 콜(system call) : 사용자 프로그램이 운영체제 내부에 정의된 코드를 실행하고 싶을 때 운영체제에 서비스를 요청하는 방법
→ 두 가지 모두 운영체제에게 CPU 제어권이 이양되어 처리되는데, 이 과정에서 프로그램 코드가 직접 인터럽트 라인을 세팅하는 명령을 실행해 발생시킨 후 제어권이 넘어가므로 넓은 의미의 인터럽트 범주에 포함
인터럽트가 발생한 경우에 처리 할 일의 절차를 의미
**프로세스 제어블록(Process Control Block: PCB)**은 운영체제가 현 시스템 내에서 실행하는 프로그램들을 관리하기 위한 자료구조
PCB는 각각의 프로그램마다 하나씩 존재하며, 실행 중이던 코드의 메모리 주소과 레지스터값, 하드웨어 상태 등이 저장됨.
프로그램 실행 중 인터럽트 발생 → 실행 상태 PCB에 저장 → CPU 제어권이 인터럽트 처리루틴으로 이양 → 처리 후 저장된 상태를 PCB에서 CPU로 복원 해 실행
오늘 날에는 정상 상태에선 CPU가 항상 사용자 프로그램에 의해 사용되며 인터럽트가 발생한 경우에만 운영체제가 CPU 제어권을 얻음.
입출력(I/O)이란 컴퓨터 시스템이 컴퓨터 외부의 입출력 장치들과 데이터를 주고 받는 것
입출력 방식에 따라 동기식 입출력과 비동기식 입출력으로 나뉘어짐
프로그램이 입출력 요청을 했을 때 입출력 작업이 완료되어야 그 프로그램이 후속 작업을 수행할 수 있는 방식
입출력이 진행되는 동안 다음 명령을 수행하지 않고 기다리기 때문에 CPU는 인터럽트를 기다리며 자원을 낭비하게 되기 때문에 입출력이 완료되는 동안 다른 프로그램에게 CPU를 이양함
운영체제는 관리를 위해 프로그램을 몇 가지 상태로 나누는데, 입출력이 완료 될 때까지 CPU가 할당 되어도 명령을 수행하지 못 할 때에는 **봉쇄 상태(blocked state)**로 전환함
다수의 입출력 연산에서 동기성 보장 방법
그러나 이렇게 되면 입출력 요청에서 동기화가 이루어지지 않기 때문에 동기성 보장을 위해 장치별로 큐(queue)를 두어 요청 순서대로 처리
각 장치마다 큐헤더가 존재하고 입출력 수행 순서를 지키기 위해 큐를 관리, 컨트롤러는 이에 맞춰 처리
CPU의 수행 속도에 비해 컨트롤러의 수행 속도나 장치의 작업 수행 틍력이 떨dj지기 때문에 CPU는 입출력이 완료될 때까지 입출력이 칠요없는 다른 프로그램을 수행
연산 완료는 인터럽트를 통해 수행하며 커널은 인터럽트 처리루틴으로 가서 입출력이 끝난 프로그램에게 CPU를 할당하도록 봉쇄 상태를 해제
입출력 연산을 요청한 후에 연산이 끝나기를 기다리지 않고 CPU 제어권을 그 프로그램에게 곧바로 다시 부여하는 방식
입출력 연산이 완료되는 것과 무관하게 수행 할 수 있는 작업이 있을 때, 혹은 읽어 오는 것이 아닌 디스크에 쓰는 요청의 경우 쓰기 작업이 완료되기 전에도 다음 명령이 수행 가능하므로 비동기식 입출력이 사용됨
비동기식 입출력에서 입출력 연산이 완료되면 동기식과 마찬가지로 인터럽트를 통해 CPU에게 알림