이전의 쉘 프로그램이 hello 프로그램을 로드하고 실행했을 때나 hello 프로그램이 메시지를 출력할때,
프로그램이 키보드나 디스플레이, 디스크나 메인 메모리를 직접 액세스 하지 않았다.
😮 오히려 운영체제(Operation System)가 제공하는 서비스를 활용한다.
0. 운영체제
- 운영체제는 '하드웨어'와 '소프트웨어' 사이에 위치한 소프트웨어 계층이다.
- '응용프로그램'이 하드웨어를 제어하려면 언제나 운영체제를 통해서 해야한다.
운영체제의 두 가지 주요 목적
1. 제멋대로 동작하는 응용프로그램들이 하드웨어를 잘못 사용하는 것을 막는다.
2. 응용프로그램들이 복잡한 저수준 하드웨어 장치들을 단순하고 균일한 메커니즘을 사용하여 조작할 수 있도록 한다.
👆 응용프로그램이 하드웨어를 직접 조작하려면 복잡하기 때문에, 운영체제가 중간다리 역할을 하여 쉽게 한다.
운영체제는 이 두가지 목적을 추상화를 통해 달성한다.
추상화: 복잡한 자료, 모듈, 시스템 등으로 부터 핵심적인 개념 또는 기능을 간추려 내는 과정
전문적인 단어가 아니라 우리가 익히 알고있는 추상화와 같은 개념이다.
- 파일: 입출력 장치의 추상화
- 가상메모리: 메인 메모리와 디스크 입출력 장치의 추상화
- 프로세스: 프로세서, 메인 메모리, 입출력 장치 모두의 추상화 결과
1. 프로세스
1) 프로세스가 있기에 가능한 것들
- hello 같은 프로그램이 최신 시스템에서 실행될 때
운영체제는 '시스템에서 이 한 개의 프로그램만 실행되는 것 같은 착각'에 빠지게 해준다. - 프로그램이 '프로세서, 메인 메모리, 입출력장치'를 모두 독차지하고 있는 것처럼 보인다.
- 프로세서는 프로그램 내의 '인스트럭션들을 다른 방해 없이 순차적으로 실행하는 것'처럼 보인다.
- 프로그램의 코드와 데이터가 '시스템 메모리의 유일한 객체인 것'처럼 보인다.
👆 이러한 환상은 전산학에서 가장 중요한 프로세스라고 하는 개념에 의해서 만들어진다.
2) 프로세스란?
CPU가 멀티코어를 가지고 있다고 하더라도 대부분의 시스템에서 프로세스를 실행할 CPU의 숫자보다 더 많은 프로세스들이 존재함. 대부분의 시스템을 기준으로 프로세스는 동시성과 병렬성을 가지며, 이를 통해 다수의 프로세스가 동시에 실행하는 것 처럼 보이게 함. 운영체제는 'Context Switching'을 통하여 여러 프로세스를 교차 수행함.
동시성(Concurrency): 하나의 CPU에서 여러개의 일을 한번에 처리. OS의 Scheduling에 따라 Context Switching을 통해 여러 테스크를 동시에 처리하는 것 처럼 보이게 함
병렬성(Parallelism): 여러개의 CPU에서 여러개의 일을 처리.
2-1) 동시 실행
- 프로세스는 실행 중인 프로그램에 대한 운영체제의 추상화다.
- 다수의 프로세스들은 동일한 시스템에서 동시에 실행될 수 있고,
각 프로세스는 '하드웨어'를 배타적으로 사용하는 것처럼 느낀다. - '동시에(concurrently)'라는 말은, 한 프로세스의 인스트럭션들이 다른 프로세스의 인스트럭션들과 섞인다는 것을 의미한다.
- 대부분의 시스템에서 프로세스를 실행할 CPU의 숫자보다 더 많은 프로세스들이 존재한다.
(이전의 시스템들은 한 번에 한 개의 프로그램만 실행할 수 있었지만, 요즘의 멀티코어 프로세서들은 여러 개의 프로그램을 동시에 실행할 수 있다.) - 어느 쪽이건 프로세서가 프로세스들을 바꿔주는 방식으로 한 개의 CPU가 다수의 프로세스를 동시에 실행하는 것처럼 보이게 해준다.
2-2) 문맥 전환
'context switching'
- 운영체제는 문맥 전환이라는 방법을 사용해서 이러한 교차실행을 수행한다.
- 운영체제는 프로세스가 실행하는 데 필요한 모든 상태정보(컨텍스트)의 변화를 추적한다.
(상태정보는 PC, 레지스터 파일, 메인 메모리의 현재 값을 포함한다.) - 어느 한순간에 단일 프로세서 시스템은 한 개의 프로세스의 코드만을 실행할 수 있다.
👉 운영체제는 현재 프로세스에서 다른 새로운 프로세스로 제어를 옮기려고 할 때
1) 현재 프로세스의 컨텍스트를 저장하고,
2) 새 프로세스의 컨텍스트를 복원시키는 문맥전환을 실행하여
3) 제어권을 새 프로세스로 넘겨준다.
4) 새 프로세스는 이전에 중단했던 바로 그 위치부터 다시 실행된다.
2-3) 커널
'kernel'
- 하나의 프로세스에서 다른 프로세스로의 전환은 운영체제 커널에 의해 관리된다.
- 커널은 운영체제 코드의 일부분으로, 메모리에 상주한다.
- 응용프로그램이 운영체제에 의한 어떤 작업을 요청하면
1) 컴퓨터는 파일 읽기나 쓰기와 같은 특정 '시스템 콜'을 실행해서 커널에 제어를 넘겨준다.
2) 그러면 커널은 요청된 작업을 수행하고 응용프로그램으로 리턴한다. - 커널은 별도의 프로세스가 아니라는 점에 유의해야 한다!
- 대신, 커널은 모든 프로세스를 관리하기 위해 시스템이 이용하는 '코드와 자료 구조의 집합'이다.
2. 쓰레드(Thread)
- 프로세스가 마치 한 개의 제어흐름을 갖는 것으로 생각할 수 있지만,
최근의 시스템에서는 프로세스가 실제로 '쓰레드'라고 하는 다수의 실행 유닛으로 구성되어 있다. - 각각의 쓰레드는 해당 프로세스의 '컨텍스트'에서 실행되며 동일한 '코드'와 '전역 데이터'를 공유한다.
- 쓰레드는 프로그래밍 모델로서의 중요성이 더욱 커지고 있다.
1. 다수의 프로세스들에서보다 데이터의 공유가 더 쉽다.
2. 쓰레드가 프로세스보다 더 효율적이다. - '다중 쓰레딩'도 프로그램의 속도를 향상시키는 데 많이 사용되는 방법이다.
2-1) 가상메모리 (Virutal Memory)
- 가상메모리는 각 프로세스들이 '메인 메모리' 전체를 독점적으로 사용하고 있는 것 같은 환상을 제공하는 추상화이다.
- 물리 메모리에서 프로세스가 작동되게 된다면, 각 프로세스는 실제 메모리 사용량은 적지만 하나의 블록을 이루어 메모리를 차지하기 때문에 메모리 누수가 일어나게 된다.
👉 이러한 부분들을 해결하기 위해 각 프로세스는 '가상주소공간'을 가진다. - 각 프로세스는 '가상주소 공간'은 프로세스 하나가 전체 메모리를 사용하는 것 처럼 동작한다.
하지만 물리 메모리에는 여러개의 블록으로 나누어져 저장되어 메모리를 효과적으로 사용할 수 있게 한다. - 리눅스에서, 주소공간의 최상위 영역은 모든 프로세스들이 공통으로 사용하는 운영체제의 코드와 데이터를 위한 공간이다.
- 주소공간의 하위 영역은 사용자 프로세스의 코드와 데이터를 저장한다.
1) 프로그램 코드와 데이터(Code and Data)
- 코드는 모든 프로세스들이 같은 '고정 주소'에서 시작하며, 다음에 'C 전역변수'에 대응되는 데이터 위치들이 따라온다.
- 코드와 데이터 영역은 '실행 가능 목적파일'인 hello로부터 직접 초기화된다.
2) 힙 (Heap)
- 코드와 데이터 영역 다음으로 런타임 힙이 따라온다.
- 크기가 고정되어 있는 코드, 데이터 영역과 달리, 힙은 프로세스가 실행되면서
C 표준함수인 malloc이나 free를 호출하면서 런타임에 동적으로 그 크기가 늘었다 줄었다 한다.
3) 공유 라이브러리 (Shared Libraries)
- 주소공간의 중간 부근에 C 표준 라이브러리나 수학 라이브러리와 같은 공유 라이브러리의 코드와 데이터를 저장하는 영역이 있다.
4) 스택 (Stack)
- 사용자 가상메모리 공간의 맨 위에 컴파일러가 함수 호출을 구현하기 위해 사용하는 '사용자 스택'이 위치한다.
- 힙과 마찬가지로 사용자 스택은 프로그램이 실행되는 동안에 동적으로 늘어났다 줄어들었다 한다.
- 특히, 함수를 호출할 때마다 스택이 커지며, 함수에서 리턴될 때는 줄어든다.
5) 커널 가상메모리 (Kernel virtual memory)
- 주소공간의 맨 윗부분은 커널을 위해 예약되어 있다.
- 응용프로그램들은 이 영역의 내용을 읽거나 쓰는 것이 금지되어 있다.
- 마찬가지로 커널 코드 내에 정의된 함수를 직접 호출하는 것도 금지되어 있다.
👉🏻 이런 작업을 수행하기 위해서는 커널을 호출해야 한다.
가상메모리가 작동하기 위해서는
프로세서가 만들어내는 모든 주소를 하드웨어로 번역하는 등의
하드웨어와 운영체제 소프트웨어 간의 복잡한 상호작용이 필요하다.
💡기본적인 아이디어는 프로세스의 '가상메모리'의 내용을 '디스크'에 저장하고, '메인 메모리'를 디스크의 캐시로 사용하는 것이다.
4. 파일 (File)
- 파일은 익히 알고 있듯 연속된 바이트들이다.
- 디스크, 키보드, 디스플레이, 네트워크까지 포함하는 모든 입출력장치는 파일로 모델링한다.
- 시스템의 모든 입출력은 '유닉스 I/O'라는 시스템 콜들을 이용하여 파일을 읽고 쓰는 형태로 이루어진다.
- 파일 개념은 매우 강력한 것이다! 응용프로그램에 시스템에 들어 있는 다양한 입출력장치들의 통일된 관점을 제공한다.
'CS > Computer System' 카테고리의 다른 글
1. RBTREE란? (0) | 2024.09.15 |
---|---|
[CS:APP] 3-4 정보 접근하기 (1) | 2024.09.04 |
[CS:APP] 1-5~1-6) 캐시 메모리, 저장장치의 계층 구조 (2) | 2024.08.27 |
[CS:APP] 1-4 프로세서의 작동 원리 (3) | 2024.08.21 |
[CS:APP] 1-2, 1-3 컴파일 시스템 (0) | 2024.08.13 |