간단히 말해 S/W와 H/W를 이어주는 역할을 하는 system S/W이다.
조금 더 정확히 말하자면,
S/W와 H/W가 맞물려 잘 돌아가게 해주는 것은 OS의 내의 Kernel이고, 그 위에 이 kernel의 기능을 이용할 수 있도록 제공되는 시스템 콜과, 이 시스템 콜의 사용을 돕는 각종 API와 유저와 OS사이의 소통을 도와주는 Shell이 추가된 것이 대개 말하는 OS의 형태이다.
Kernel : OS의 핵심이며, 시스템 내 모든 것을 컨트롤 할 수 있다. 언제나 메모리에 상주하고 있으며 S/W와 H/W 간의 상호작용을 담당한다. Device driver를 통해 모든 H/W를 제어하고, 자원과 관련 된 프로세스 간 충돌을 중재 & 제어하며 CPU 자원 및 캐시 사용량, 파일 시스템, 네트워크 소켓 등의 공용 자원의 활용을 최적화 한다.
System calls : Kernel의 각 기능을 이용할 수 있게끔 제공되는 명령 또는 함수를 말한다.
API : 시스템 콜을 사용해서 만든 언어 별 API들이다.
Shell : OS의 인터페이스이다. 간단히 말해 OS와의 소통 창구를 제공한다. 대개 CLI/GUI 환경 둘 다 제공된다. Shell은 프로그램을 시작하고 제어할 뿐만 아니라 프로세스와 파일을 제어하는 프로그래밍 언어를 통합한다. 또한, 사용자에게 입력을 요청하고 해당 입력을 OS에 대해 해석한 다음 OS의 결과 출력을 처리하여 사용자와 OS 간의 상호 작용을 관리한다.
OS는 간단히 말해 H/W resource management를 해준다. 그래서 사용자나 응용 프로그램이 해당 H/W의 조작법을 따로 알거나 작성하거나 하지 않아도 요청을 받아서 H/W 조작을 해 준다.
예를 몇 개 들어보면,
등이 있다.
만약 OS가 없다면?
컴퓨터를 여전히 사용할 수는 있을 것이다. 하지만 모든 응용 프로그램은 자체적인 UI를 제공해야 할 것이며, 또한 디스크 저장소 or 네트워킹 등과 같은 기본 컴퓨터의 low-level 기능을 처리하는 데 필요한 코드들이 포함되어야 한다.
이는 S/W의 크기를 쓸 데 없이 크게 하며, 그에 따라 비실용적인 개발 비용의 상승이 일어날 것이다.
Kernel은 이처럼 강력한 권한들을 지니고 있으며 동시에 이 권한들에 아무 응용 프로그램이 액세스 하는 것을 막는다.
그렇기에 kernel 내부에서도 특히나 중요한 기능(프로세스 동작, SSD와 같은 H/W 관리, 인터럽트 관리 등)을 담당하는 코드들은 메모리 내에서도 분리되어 있는 공간에 따로 로드되어 외부의 접근으로부터 보호된다.
응용 프로그램은 통상적으로 user mode에서 실행이 된다.
그러다가, 예를 들어, 어떤 파일을 읽어야 한다던지 하면
응용 프로그램에는 디스크를 열람할 수 있는 권한이 없기 때문에 시스템 콜을 호출해 커널에 이 작업을 요청한다.
커널에서는 해당 작업을 처리하고 결과를 반환해 준다.
file = File.open("C://txtfile.txt"); 등과 같은 코드를 실행하면 이렇게 user mode과 kernel mode 사이를 왔다갔다 하며 작업을 처리한다.
그러니까 아래 그림과 같은 현상이 일어나는 이유는 해당 system call의 사용 권한을 부여 할 지 말 지를 결정해달라는 것이다.
초고속 인터넷 붐이 일어났던 한국의 90년대 후반~2000년 초반 쯤에는 낮은 보안 의식으로 인해 각종 해킹 프로그램과 바이러스들에 의해 디스크의 파일들이 모조리 날아가는 일이 종종 일어나곤 했다. 이번 포스팅의 내용과 연관지어 생각해보면, 생각 없이 kernel mode 이용 권한을 마구 부여했기 때문이었다는 걸 알 수 있다.
그래서 mode가 변한다는 것을 누가 인식하느냐? 정확히 뭐가 변하는 거냐? 라고 한다면, cpu가 인식하고 cpu가 변한다.
CPU protection rings / CPU privilege rings 라고 불리는 그림이다.
Layer로 표시되는 각 ring은 cpu 이용 권한을 의미하며,
Ring 0이 Kernel mode, System mode, privileged mode.
Ring 3가 User mode, least privileged mode, slave mode, restricted mode
를 뜻한다.
User mode에서 Kernel mode가 되면 CPU는 kernel이 사용 중인 상태가 되어 각종 H/W나 드라이버들에 대한 접근을 제한 없이 한다.
그러다 다시 user mode가 되면 그러한 권한들이 소거된다.
작업, task, job 등의 용어와 혼용하여 사용되기도 하며 간단히 말해
현재 메모리에 올라 와 있는 프로그램을 실행시키는 일꾼을 뜻한다.
프로그램과 프로세스는 1:1 대응 관계가 아닌, 1개의 프로그램을 온전히 돌리기 위해 여러 개의 프로세스가 필요하기도 하다.
크롬 하나를 돌리기 위해 17개의 프로세스가 열 일 하는 중이다.
각 프로세스는 고유의 stack, heap, data, text area를 가지고 있으며, 프로세스 간에는 서로의 내부 데이터나 작업에 대한 간섭 및 관측이 불가능하다.
Text : 프로그램의 코드가 저장된다.
Data : 초기화 된 데이터, 변수 등이 있다.
Heap : 동적 할당되는 데이터에 이용되며 객체 생성에도 이용이 된다. 꽉 차면 객체 생성 불가능.
Stack : 함수 리턴 주소, 로컬 변수 등이 저장된다. 프로세스 생성 및 실행 시 가장 먼저 프로세스 종료 시 리턴 주소가 저장된다.
Process의 상태 변화를 나타낸 다이어그램이다.
fork()는 시스템 콜의 하나로 하나의 프로세스를 상속해 자식 프로세스를 새로 만들어 낸다.
자식 프로세스는 부모 프로세스로부터 대부분의 값을 전달받는다. 그래서 필요한 부분만 수정하면 새 프로세스로서 활동이 가능하다.
id
를 할당받는다.id
를 리턴하고,0
을 리턴한다.-1
를 리턴한다.프로세스 생성 시에 해당 프로세스의 정보를 담은 PCB라는 것도 함께 생성이 된다.
PCB (Process Control Block)은 OS kernel의 자료 구조로써 kernel이 process management를 할 때 필요한 정보들이 담겨있다. 이 PCB는 위에서 말했던 따로 보호되는 메모리 공간 (Kernel space)에 저장이 된다.
OS의 작업은 프로세스 단위로 이루어지기 때문에 이 프로세스를 어떻게 스케쥴링 하는가에 대한 여러 방법론이 있다.
Batch Processing : 자동으로 다음 프로세스를 순차적으로 실행한다. 이게 없으면 파일을 여러 개 열어야 한다고 할 때, 하나 열고 열릴 때까지 기다렸다가 또 하나 열고를 반복해야 한다.
대신 한 번에 하나의 프로세스 밖에 실행하지 못하기 때문에 음악을 들으면서 블로그 포스팅을 한다거나 하는 일은 못한다. 음악을 다 듣고 하던 지, 할 일을 하고 음악을 듣던 지 해야 한다.
Multi-programming : 하나의 CPU에서 여러 프로그램을 동시에 실행(하는 것처럼 보이게 하는) 기능이다.
정확히 말해서, CPU 유휴 시간을 줄이기 위해 메인 메모리에 2개 이상의 프로그램을 올려놓고 돌리는 것이다.
기본적으로는 하나의 프로세스를 실행하다가 그 프로세스가 I/O interaction 등이 필요해서 대기 시간을 가지게 되면, 대기하라고 냅두고 대기 중인 다른 프로세스를 가져다가 실행한다. 그러다 인터럽트가 발생하면 다시 원래 프로세스를 불러다가 실행한다.
이를 위해 Context Switching이 필요하다.
Multi-tasking (MT) : 하나의 CPU에서 여러 개의 프로세스를 동시에 실행(하는 것처럼 보이게 하는) 기능이다.
Multi-programming (MP)과 헷갈릴 수 있다. 왜냐하면 MT 자체가 MP의 논리적 확장판인데다가, MP에 Round-robin scheduling Algorithm을 더하면 이게 MT이기 때문이다.
간단히 보충 설명하자면, MP는 I/O interaction이 요구되어 대기가 필요해지는 때에만 프로세스를 갈아끼운다.
반면, MT는 MP의 조건에 더해서 프로세스에 대한 CPU 할당 시간이 다 하면 이 때도 프로세스를 갈아끼운다.
이를 위해 Context Switching과 Time Sharing 기술이 요구된다.
Time Sharing : 이전 포스팅에서 CPU에 대해 설명할 때 나왔던 그 시분할 기술이다.
1, 2, 3의 프로세스가 있다면 이를 1-1, 2-1, 3-1, 1-2, 2-2, 3-2 이렇게 나누어 번갈아 실행해 응답 시간을 높여준다.
즉, 사용자 입장에서는 3개의 작업 모두가 바로바로 실행되는 것처럼 보인다는 것이다.
하지만 TS의 원래 목표는 네트워크 구조에서 하나의 서버 컴퓨터에 여러 사용자가 접속해 각자의 프로그램을 돌린다고 했을 때, MP와 MT기법을 활용해 모두가 자기 프로그램이 실시간으로 바로 돌아간다고 느끼게 하는 것이다.
바로 밑에 그림처럼.
CPU 자원을 차지하던 (running state) process를 내보내고 다른 process를 CPU에 할당하는 작업이다.
위는 Context Switching 과정을 보여주는 그림이다.
Context Switching이 일어나는 이유는 3가지이다.
CPU 할당 시간이 다 했거나 (time sharing) -> ready state로,
I/O 작업이 필요해졌거나 (multi-programming) -> wait state로,
Interrupt가 발생했거나 -> ready state
상태 변화가 일어나게 된다. 밑에 그림 참조.
실행 될 프로세스를 CPU에 할당해주는 모듈을 Dispatcher라고 하는데 그래서 그 할당 과정을 Dispatch라고 한다.
또한 Context Switching에 들어가는 시간(Running process를 내리고 Ready process를 올리고)을 Dispatch Latency라고 한다. 이 때 CPU는 딱히 일을 하지 않는다.
너무 잦은 Context Switching이 발생하면 이 Dispatch Latency가 쓸데없이 늘게 되고, 그럼 CPU가 계속 놀게되니 좋을 게 하나 없다.
다음글 : 프로세스 스케쥴러, IPC