본 글은 반효경 교수님의 운영체제 강의를 들으며 정리하는 글 입니다.
1. 동기식 입출력과 비동기식 입출력
1 - 1) 동기식 입출력 vs 비동기식 입출력
바로 위 그림은 동기식(Synchronous)입출력과 비동기(Asynchronous)식 입출력의 비교해 보여 준다.
사용자가 입출력 요청을 하면 동기식 입출력에서는 먼저 운영체제의 커널로 CPU의 제어권이 넘어가서 입출력 처리와 관련된 커널의 코드가 수행된다.
이때 입출력을 호출한 Process의 상태를 Blocked 상태로 바꾸어 요청한 입출력이 완료될 때까지 CPU를 할당받지 못하게 된다.
입출력이 완료되면 I/O 컨트롤러가 CPU에게 인터럽트를 발생시켜 입출력이 완료되었음을 알려주고, Blocked 상태인 해당 프로세스에게 CPU를 할당받을 수 있는 권한을 준다. 권한을 준다는 이야기는 CPU를 할당 받을 수 있는 줄(대기 Queue)에 서게 될 수 있다는 뜻이다.
반면 비동기식 입출력에서는 CPU의 제어권이 입출력을 요청한 Process에게 곧바로 다시 주어지며, 입출력 연산이 완료되는 것과 무관하게 다른 처리 가능한 작업을 수행한다.
즉, 동기식은 Process의 요청에 대한 응답을 받을때까지 해당 Process가 멈추게 되고,
비동기식은 Process의 요청에 대한 응답을 받기 전까지 해당 Process에서 다른 작업을 수행하게 된다.
두 방식 모두 입출력 연산이 완료되면 인터럽트를 통해 CPU에게 알려주게 된다.
1 - 2) 동기식 입출력 (Synchronous I/O)
동기식 입출력은 입출력 요청 후 입출력 작업이 완료된 후에야 제어가 사용자 프로그램에 넘어가는 것을 말한다.
예를 들어, 프로그램이 SSD로부터 어떤 정보를 읽어 오라는 요청을 했을 때 SSD 입출력이 완료되기까지는 어느 정도의 시간이 소요되는데...
이때 다음처럼 2가지 방식으로 동기식 입출력을 구현할 수가 있습니다!
▶ 구현 방법 1
- 입출력이 끝날 때까지 인터럽트를 기다렸다가, 끝나면 사용자 프로그램에게 CPU의 제어권을 넘긴다.
- 매 시점 하나의 입출력만 일어날 수 있다.
- CPU를 낭비한다는 문제가 있다.
- 입출력 장치 또한 하나만 사용하게 되어 낭비이다.
- CPU를 낭비시키는 구현 방법
▶ 구현 방법 2
- 입출력이 완료될 때까지 해당 Process에서 CPU의 제어권을 빼앗는다.
- 다른 Process에게 CPU의 제어권을 넘긴다.
- CPU가 놀지 않고 계속 일하게 된다.
- I/O 장치 또한 놀지 않고 동시에 여러개가 일을 할 수 있다.
- 보통 동기식 입출력 구현 방법
2. 서로 다른 입출력 명령어
I/O를 수행하는 2가지 방법이 있다.
1) 일반적인 I/O
2) Memory Mapped I/O
2 - 1) 일반적인 I/O
메모리에 접근하는 인스트럭션과 I/O 장치를 접근해야 하는 인스트럭션이 구분되어 있다.
메모리 주소가 있듯, I/O Device도 주소가 있어서 특정 주소에 대해서 I/O 접근하는 인스트럭션을 실행하면 해당 Device에 접근하게 된다.
2- 2) Memory Mapped I/O
I/O 장치도 메모리 주소에 연장 주소를 붙여 접근할 수 있다.
즉, 메모리에 접근 하는 인스트럭션을 통해서 I/O에 접근할수가 있다.
예를 들어 100번지에 접근하면 메모리에 접근한다면, 1000번지에 해당하는 메모리에 접근하는 명령은 사실은 I/O를 하는 인스트럭션을 뜻할 수 있다.
3. 저장 장치 계층 구조
위로 갈수록 속도가 빠르지만, 단위 공간당 가격이 비싸고 용량이 적다.
아래로 갈수록 가격은 싸고 용량이 많지만, 속도가 느려진다.
3 - 1) Primary Storage vs Secondary Storage
CPU는 바이트 단위로 접근 가능한 매체이어야 접근이 가능하다.
▶ Primary Storage
CPU에서 직접 접근할 수 있는 매체를 말하며, Executable (실행 가능하다)라고 부른다.
즉, 해당 저장소는 바이트 단위로 CPU 접근이 가능하므로 Primary라고 부르며 전원이 꺼지면 데이터가 사라지는 휘발성 특징을 갖는다.
▶ Secondary Storage
CPU가 직접 접근하지 못하는 매체를 말한다.
하드 디스크의 단위는 섹터 단위이므로 CPU가 접근하지 못해서 Secondary라고 부른다.
해당 저장소는 전원이 꺼져도 데이터가 보존되는 비휘발성 특징을 갖는다.
3 - 2) 캐시 메모리
캐시 메모리는 CPU와 메인 메모리의 속도 차이를 완충하기 위해 존재한다.
용량이 적기 때문에 모든 것을 담아 둘 수는 없으나, 빈번히 사용되는 필요한 정보를 선별적으로 저장하여 재사용하는 캐싱 기법을 통해 시스템의 성능을 높일 수 있다.
4. 프로그램은 어떻게 실행되는가?
프로그램은 File System에 실행 파일 형태로 저장되어 있다. 실행시키게 되면 메모리에 올라가 Process가 된다.
정확히 물리적인 메모리에 바로 올라가는 것이 아니라 한 단계를 거치는데, 이를 가상 메모리(Virtual Memory)단계를 거친다고 한다.
이때 독자적인 메모리 주소 공간이 형성되는데 code, data, stack 영역으로 구성되어 있다.
4 - 1) Virtual Memory?
사용하지 않으면 메모리에서 쫓아 버리는 게 아니라 Disk에 내려놓게 된다. (이러한 용도의 공간을 Swap area라고 한다)
메모리 낭비를 방지하기 위해 프로그램 중 당장 실행에 필요한 부분만 올라가고, 그렇지 않은 부분은 디스크 중 메모리의 연장 공간으로 사용되는 스왑 영역에 내려 놓는다.
즉, 주소 공간을 쪼개서 어떤 부분은 메모리에 있고, 어떤 부분은 Swap area에 있게 된다.
이런 기법을 Virtual Memory라고 부르기도 하지만, 사실 각 프로그램마다 독자적으로 가지고 있는 메모리 주소 공간을 Virtual Memory라고 한다.
[Disk 활용]
Disk의 Swap area는 메모리 연장 공간(휘발성)으로 사용하고, File System은 비휘발성 용도로 사용한다
▶ Code
CPU에서 실행할 기계어 코드를 저장한다.
▶ Data
전역 변수 등 프로그램이 사용하는 데이터를 저장한다.
▶ Stack
함수가 호출될 때 호출된 함수의 수행을 마치고 복귀할 주소 및 데이터를 임시로 저장한다.
5. 커널 주소 공간의 내용
5 - 1) Code
운영체제는 CPU, 메모리 등의 효율적으로 자원을 관리하는 역할을 하는데, 이때 필요한 코드들이 담겨 있다.
사용자에게 편리한 인터페이스를 제공하기 위한 부분이 주를 이루고 있다.
이 밖에도 커널의 코드는 시스템 콜 및 인터럽트를 처리하기 위한 부분을 포함한다.
5 - 2) Data
각종 자원을 관리하기 위한 자료 구조가 저장된다.
CPU나 메모리와 같은 하드웨어 자원을 관리하기 위한 자료 구조뿐 아니라 프로세스를 관리하기 위한 자료 구조(PCB)도 커널의 데이터 영역에 유지된다.
커널의 데이터 영역 내에는 각 프로세스의 상태, CPU 사용 정보, 메모리 사용 정보 등을 유지하기 위한 PCB를 두고 있다.
5 - 3) Stack
프로그램의 스택 영역과 마찬가지로 함수 호출 시의 복귀 주소를 저장하기 위한 용도로 사용된다.
하지만 커널의 스택은 일반 사용자 프로그램의 스택과 달리 현재 수행 중인 프로세스마다 별도의 스택을 두어 관리한다.
이는 일반 사용자 프로그램이 자기 주소 영역 내부의 함수를 호출하면 자신의 스택에 복귀 주소를 저장하지만, 프로세스가 커널에 정의된 시스템 콜을 호출하면, 시스템 콜 내부에서 다른 함수를 호출하는 경우에는 복귀 주소가 커널 내의 주소가 되므로 커널의 스택 영역에 저장되어야 하기 때문이다.
즉, 프로그램이 자기 자신의 코드 내에서 함수 호출 및 복귀 주소를 유지하기 위해서는 자기 주소 공간 내의 스택을 사용하고, 시스템 콜이나 인터럽트 등으로 운영 체제의 코드가 실행되는 중에 함수 호출이 발생할 경우 커널 공간 내의 스택을 사용한다.
6. 사용자 프로그램이 사용하는 함수
6 - 1) 사용자 정의 함수
자신의 프로그램에서 정의한 함수를 말한다.
6 - 2) 라이브러리 함수
자신의 프로그램에서 정의하지 않고 가져다 사용한 함수를 말하며, 자신의 프로그램 실행 파일에 포함되어 있다.
6 - 3) 커널 함수
운영 체제 프로그램의 함수를 말하며, 커널 함수의 호출은 곧 시스템 콜을 호출하는 것 이다! (커널 코드 안에 있는 함수)
만약 사용자 프로그램이 커널 함수를 호출하면, 해당 코드들은 커널 주소 공간에 있어서 넘어가야 하지만 사용자 코드에서 직접적으로 접근할수는 없다.
따라서 커널 함수를 호출할때는 시스템 콜을 통해 인터럽트 라인을 세팅하여 CPU에게 제어권을 넘겨야 한다.
7. 프로그램의 실행
직전 그림은 사용자 프로그램 입장에서 본 실행 및 종료 과정이다.
프로세스 A가 CPU에서 실행되고 있다고 하면, 이는 자신의 주소 공간에 정의된 코드를 실행하는 것과 커널의 시스템 콜 함수를 실행하는 것으로 나누어 볼 수 있다.
전자를 사용자 모드(Mode bit이 1)에서의 실행 상태라고 하고, 후자를 커널 모드(Mode bit이 0)에서의 실행 상태라고 한다.
이때 한 가지 주의할 점은 비록 시스템 콜을 통해 실행되는 것이 프로세스 A의 코드가 아닌 운영 체제 커널의 코드이지만, 시스템 콜이 수행되는 동안 커널이 실행 상태에 있다고 하지 않고 프로세스 A가 커널 모드에서 실행 상태에 있다고 부른다.
프로세스 A 입장에서는 CPU를 운영 체제 커널에 빼앗긴 것으로 생각할 수 있지만, 사실 프로세스 A가 해야 할 일을 시스템 콜을 통해 커널이 대행하고 있는 것이기 때문이다.
8. 출처
https://hyojaedev.tistory.com/29
'CS > OS (2022-1)' 카테고리의 다른 글
[OS] Process Management (0) | 2022.11.22 |
---|---|
[OS] Process - 2 (0) | 2022.11.21 |
[OS] Process - 1 (0) | 2022.11.21 |
[OS] System Structure & Program Execution 1 (0) | 2022.11.19 |
[OS] Introduction to Operating Systems (0) | 2022.11.18 |
댓글