운영체제는 시스템 자원, 응용 프로그램을 관리하는 주체입니다. 또한, 하드웨어가 원활히 작동하도록 일을 시키는 주체입니다.
시스템 자원은 하드웨어를 구성하는 일을 하는 CPU, 자료를 저장하는 RAM, 디스크 등이 있습니다.
운영체제가 없다면 응용 프로그램이 실행될 수 없습니다. 응용 프로그램은 컴퓨터를 이용해 다양한 작업을 하는 것이 목적입니다. 운영체제는 응용 프로그램이 하드웨어에게 일을 시킬 수 있도록 도와줍니다.
또한, 응용 프로그램이 실행되면 시스템 자원을 활용할 수 있는 권한, 사용자를 관리합니다. 이 부분이 없다면, 내 컴퓨터에 접근한 모든 유저가 내 컴퓨터에 저장된 자료들을 열람 및 사용할 수 있기 때문에 관리가 필요합니다.
권한을 부여받은 응용 프로그램은 이제 운영체제가 제공하는 기능을 이용할 수 있습니다. 응용 프로그램이 운영체제와 소통하기 위해선 운영체제가 응용 프로그램을 위해 인터페이스(API)를 제공해야 합니다.
응용 프로그램이 시스템 자원을 사용할 수 있도록 운영체제에서 다양한 함수를 제공하는 것을 시스템 콜(System Call) 이라 부릅니다.
예를 들어, 워드프로세서 응용 프로그램이 프린터(시스템 자원) 를 사용하여 인쇄(하드웨어의 동작) 하기 위해 워드프로세서 응용 프로그램은 운영체제로부터 프린터 사용에 대한 권한을 부여받아야 합니다.
워드프로세서가 프린터 사용에 대한 권한을 획득하면, 프린터를 사용할 때 필요한 API를 호출해야 합니다. 이 API는 시스템 콜로 이루어져 있습니다.
어릴 때, 문서를 출력할 때 위와 같은 오류를 보곤 했습니다.
오류 메세지의 시스템 호출이 위에서 말한 시스템 콜
입니다. 그리고, 위와 같은 오류를 해결하기 위해선 보통 프린터 드라이버 를 업데이트하거나, 윈도우 버전을 업데이트하면 개선이 됐었던 기억이 납니다.
한글 워드 프로세서가 프린터 사용에 대한 권한을 획득했고, 출력하기 위해선 이 프린터를 사용할 때 필요한 인터페이스(API)를 호출해야 합니다.
이 인터페이스가 프린터 드라이버라고 생각을 했고, 이 인터페이스 업데이트 하는 것으로 위 오류를 개선할 수 있구나 하고 생각하게 됐습니다. 만약, 제가 이해한게 다르다면 댓글로 피드백 부탁드립니다!
프로세스는 운영체제에서 실행 중인 하나의 애플리케이션입니다.
사용자가 애플리케이션을 실행하면, 운영체제로부터 실행에 필요한 메모리를 할당받아 애플리케이션 코드를 실행합니다. 이때 실행되는 애플리케이션이 프로세스입니다.
인터넷 브라우저를 두 개 실행하면, 두 개의 프로세스가 생성됩니다. 하나의 애플리케이션은 여러 프로세스를 만들 수 있습니다.
운영체제에서 실행 중인 프로세스는 작업 관리자, 또는 활성 상태창에서 쉽게 확인할 수 있습니다.
스레드는 하나의 작업을 실행하기 위해 순차적으로 실행한 코드의 이어짐입니다.
하나의 스레드는 코드가 실행되는 하나의 흐름이며, 한 프로세스 내에 스레드가 두 개라면 코드가 실행되는 흐름이 두 개 생긴다는 의미입니다.
멀티 태스킹은 두 가지 이상의 작업을 동시에 처리하는 것을 의미합니다.
동시에 두 부대의 뮤탈리스크를 컨트롤하는 이제동 선수...
운영체제는 멀티 태스킹을 할 수 있도록, 프로세스마다 CPU 및 메모리 자원을 적절히 할당하고 병렬로 실행합니다.
예를 들어 워드로 문서작업을 하면서, 동시에 유튜브에서 음악을 들을 수 있습니다.
물론 멀티 태스킹은 꼭 멀티 프로세스를 의미하는 것은 아닙니다. 하나의 프로세스 내에서 멀티 태스킹을 할 수 있도록 만들어진 애플리케이션도 있습니다. 하나의 프로세스가 어떻게 두 가지 이상의 작업을 처리할 수 있을까요?
멀티 프로세스가 애플리케이션 단위의 멀티 태스킹이라면, 멀티 스레드는 애플리케이션 내부에서의 멀티 태스킹이라고 할 수 있습니다.
멀티 스레드는 다양한 곳에서 사용됩니다. 대용량 데이터의 처리시간을 줄이기 위해 데이터를 분할하여 병렬로 처리하는 데에 사용할 수도 있고, UI를 가지고 있는 애플리케이션에서 네트워크 통신을 하기 위해 사용할 수도 있습니다. 그리고 여러 클라이언트의 요청을 처리하는 서버를 개발할 때에도 사용됩니다.
위 그림처럼, 하나의 프로세스 안에서 각각의 스레드가 병렬로 처리되고 있고, 그 스레드 각각 registers
와 stack
을 갖고 있습니다. 각 스레드는 다른 스레드와 독립적으로 동작합니다.
여기서 stack
은 call stack
이라고도 부르는데, 이는 실행 중인 서브 루틴을 저장하는 자료 구조입니다.
이 멀티 스레딩으로 얻을 수 있는 이점은 아래와 같습니다.
프로세스를 이용하여 동시에 처리하던 일을 멀티 스레딩을 사용하는 것으로 메모리 공간과 시스템 자원의 소모가 줄어듭니다.
위 그림에서 보듯, 프로세스를 여러개 실행하여 처리한다면 프로세스마다 code
,data
,files
를 사용하게 되는데, 이는 프로세스의 전역 변수 공간 또는 동적으로 할당된 공간 Heap
입니다. 즉, 여러개의 프로세스는 이 공간들을 더 사용하는 것이기 때문에 시스템의 처리량이 멀티 스레딩에 비해 낮고, 자원 소모가 더 큽니다.
멀티 스레딩은 하나의 Heap
을 사용하는 것으로, 프로세스 간 통신 방법(IPC)에 비해 간단하게 스레드 간 통신을 할 수 있습니다. 이를 통해 시스템 처리량의 향상, 시스템 자원의 소모를 줄일 수 있습니다. 최종적으로, 프로그램의 응답 시간이 단축됩니다.
단점으로는, 멀티 스레딩 기반 프로그래밍을 하는 경우 공유하는 자원에 대해 고민해야합니다.
서로 다른 스레드는 데이터를 사용하기 위해 같은 Heap
에 접근합니다. 서로 다른 스레드가 서로 사용하는 변수나 자료구조에 접근하는 경우, 예상 밖의 값을 읽어오거나 수정할 수 있기 때문입니다.
동시에 돌릴 수 있는 스레드 수는 컴퓨터에 있는 코어 갯수로 제한됩니다. 운영체제(또는 가상 머신)는 각 스레드를 시간에 따라 분할하여, 여러 스레드가 일정 시간마다 돌아가면서 실행되도록 합니다. 이런 방식을 시분할이라고 합니다.
Concurrency(동시성, 병행성): 여러 개의 스레드가 시분할 방식으로 동시에 수행되는 것처럼 착각을 불러일으킴
Parallelism(병렬성): 멀티 코어 환경에서 여러 개의 스레드가 실제로 동시에 수행됨
자바스크립트는 싱글 스레드 언어입니다. 싱글 스레드는 한 번에 하나의 작업만 수행할 수 있습니다. 그러나, 자바스크립트를 사용하는 환경에서 비동기적으로 작업을 수행할 수 있습니다.
자바스크립트는 싱글 스레드로 동작하는데, 어떻게 비동기 작업을 수행할 수 있을까요?
자바스크립트가 실행될 땐 다음과 같은 요소들이 실행을 돕습니다.
예제를 통해서 위 요소들로 어떻게 싱글 스레드인 자바스크립트가 비동기작업을 하는지 이야기해보겠습니다.
세 개의 수행해야할 작업이 있습니다.
첫 번째 작업은 함수 logA()
를 실행하는 것입니다.
두 번째 작업은 Web API인 setTimeout(logB, 0)
를 실행합니다.
세 번째 작업은 함수 logC()
를 실행합니다.
순서 상으로 보면, 콘솔 창에 찍히는 결과는 A, B, C
가 되어야 합니다.
작업이 수행되는 과정을 보겠습니다.
먼저, 수행해야 할 작업들을 담아야 합니다. 가장 먼저 logA()
를 읽었습니다. 자바스크립트 함수이므로, Call Stack에 담습니다.
setTimeout(logB, 0)
을 읽었습니다. Web API에서 제공하는 API입니다. Web API 이름의 공간에 담습니다.
logC()
를 읽었습니다. 자바스크립트 함수이므로 Call Stack에 담습니다.
작업을 모두 탐색했고, 이제 Call Stack에 담긴 작업들을 순차적으로 처리합니다. logA()
와 logC()
를 순차적으로 처리합니다. 콘솔에 A
, C
가 찍혔습니다.
Web API에 담긴 setTimeout(logB, 0)
는 Callback Queue에 담깁니다.
Callback Queue는 Call Stack이 비어있는 경우, Event Loop를 통해 Callback Queue의 작업을 Call Stack에 담습니다.
Call Stack에 담긴 setTimeout(logB, 0)
를 실행합니다.
최종적으로 콘솔에 A
, C
, B
가 찍혔습니다.
위와 같이, 자바스크립트는 싱글 스레드로 여러 요청을 처리할 수 있습니다.