icon

안동민 개발노트

1장 : 운영체제 소개

운영체제란 무엇인가


스마트폰에서 앱을 열고, 노트북에서 브라우저를 띄우고, 서버에서 API 요청을 처리하는 모든 순간 — 그 이면에서 하드웨어를 조율하는 소프트웨어가 운영체제(Operating System, OS)입니다.

개발을 시작하면 대부분 프로그래밍 언어의 문법부터 배웁니다. 변수를 선언하고, 함수를 호출하고, 라이브러리를 가져다 쓰면 프로그램이 돌아갑니다. 그런데 한 번이라도 서버가 죽어 새벽에 호출을 받았다거나, 멀티스레드 환경에서 재현 불가능한 버그를 만난 적이 있다면, 그 순간부터 내 코드 아래에서 무슨 일이 일어나고 있는 걸까?라는 궁금증이 생겼을 것입니다. 운영체제를 공부하는 것은 바로 그 질문에 답하는 과정입니다.

이 절에서는 운영체제가 무엇이고, 왜 존재하며, 개발자에게 어떤 의미가 있는지를 잡아두겠습니다. 이후의 모든 장 — 프로세스, 스레드, 메모리, 파일 시스템, 동기화 — 은 이 절에서 제시하는 큰 그림 위에 세부 사항을 채워넣는 과정입니다.


OS의 정의와 역할

운영체제는 컴퓨터 하드웨어와 사용자(또는 애플리케이션) 사이의 중재자입니다. 비유하자면, 대형 레스토랑의 총지배인(General Manager)과 비슷합니다. 손님(사용자)은 메뉴만 보고 주문하면 되고, 셰프(CPU), 냉장고(메모리), 저장 창고(디스크) 등의 자원을 누가 언제 어떻게 쓸지는 총지배인이 조율합니다. 손님이 주방에 직접 들어가서 불을 켜지 않아도 되는 것처럼, 프로그래머도 디스크의 섹터 번호를 직접 지정하지 않아도 됩니다.

운영체제의 핵심 역할은 크게 두 가지로 나뉩니다.

자원 관리자(Resource Manager)로서, CPU, 메모리, 디스크, 네트워크 같은 하드웨어 자원을 여러 프로그램이 효율적으로 공유할 수 있도록 관리합니다. 하나의 CPU를 여러 프로세스가 번갈아 쓰게 하고, 한정된 메모리를 프로세스마다 나누어 할당하며, 디스크 접근 순서를 조율합니다. 만약 이 조율자가 없다면, 한 프로그램이 메모리를 독점해 다른 프로그램이 실행조차 되지 못하거나, 두 프로그램이 같은 디스크 영역을 동시에 수정해 데이터가 뒤섞이는 일이 발생할 것입니다.

자원 관리의 핵심 과제는 공정성(Fairness)효율성(Efficiency) 사이의 균형입니다. 모든 프로그램에 완전히 동등한 CPU 시간을 주면 공정하지만, 긴급한 작업이 느려질 수 있습니다. 반대로 효율만 추구하면 일부 프로그램이 무한정 대기하는 기아(Starvation) 상태에 빠질 수 있습니다. 이 균형을 잡는 것이 스케줄링, 메모리 관리, I/O 관리의 핵심 주제이며, 이 교재 전체에서 반복적으로 다루게 될 주제입니다.

인터페이스 제공자(Abstraction Provider)로서, 복잡한 하드웨어의 세부사항을 숨기고 단순한 추상화를 제공합니다. 프로그래머가 디스크의 섹터 번호를 직접 계산할 필요 없이 open("file.txt")로 파일을 열 수 있는 것은, OS가 "파일"이라는 추상화를 제공하기 때문입니다. 네트워크 통신을 할 때 이더넷 프레임을 직접 조립하지 않고 socket()send()를 호출하면 되는 것도 같은 원리입니다.

이 추상화 덕분에 같은 C 프로그램이 Intel CPU에서도, ARM CPU에서도 — 하드 디스크에서도, SSD에서도 — 코드 수정 없이 동작할 수 있습니다. 운영체제가 하드웨어의 차이를 흡수해주기 때문입니다. 이것은 단순한 편의 기능이 아니라, 소프트웨어 산업이 생산성을 유지할 수 있게 하는 근본적인 구조입니다.


사용자 관점 vs 시스템 관점

같은 운영체제라도 보는 관점에 따라 초점이 완전히 달라집니다. 이 차이를 이해하면 좋은 OS에 대한 기준이 상황에 따라 다르다는 것을 알 수 있습니다.

사용자 관점에서 OS는 편의성과 응답성이 중요합니다. 데스크톱 OS는 마우스 클릭에 즉각 반응하고, 여러 앱을 동시에 실행할 수 있어야 합니다. 브라우저에서 유튜브를 보면서 코드 에디터를 열고, 동시에 슬랙 메시지를 받을 수 있어야 합니다. 이 모든 것이 "끊김 없이" 동작하는 것처럼 보이는 것은 OS가 CPU 시간을 수 밀리초 단위로 잘게 나누어 각 프로그램에 분배하기 때문입니다.

스마트폰 OS는 여기에 더해 배터리 효율이라는 제약이 추가됩니다. 터치에 빠르게 응답하면서도, 백그라운드 앱이 배터리를 과도하게 소모하지 않도록 관리해야 합니다. Android의 Doze 모드, iOS의 Background App Refresh 제한이 이 문제를 해결하는 OS 수준의 메커니즘입니다.

시스템 관점에서 OS는 자원의 효율적 활용이 핵심입니다. 서버 OS는 CPU 이용률을 최대화하고, 가능한 많은 요청을 처리하며, 장애를 빠르게 복구해야 합니다. 초당 수만 건의 API 요청을 받는 서버에서 CPU가 30%만 사용되고 있다면 자원 낭비이고, 100%에 가깝게 쓰이면서도 응답 시간이 안정적이면 잘 튜닝된 시스템입니다.

임베디드 OS(자동차 ECU, 의료 장비, 산업 제어기)는 또 다른 기준이 적용됩니다. 실시간성(Real-time)이 핵심입니다. 제한된 메모리와 전력 안에서, 정해진 시간 내에 반드시 작업을 완료해야 합니다. 자동차의 에어백 제어기가 보통 10ms 안에 동작하지만 가끔 100ms 걸린다면 쓸 수 없습니다. 항상 데드라인을 지켜야 합니다.

관점핵심 목표예시
데스크톱 사용자응답성, 편의성Windows, macOS
모바일 사용자응답성 + 배터리 효율Android, iOS
서버 관리자처리량, 안정성Linux Server
임베디드 시스템실시간성, 최소 자원RTOS, VxWorks

운영체제가 없다면

OS의 가치는 없을 때를 상상하면 가장 명확해집니다. 아래 시나리오 각각이 운영체제의 핵심 기능 하나에 대응됩니다.

시나리오 1 — CPU 공유: CPU가 하나뿐인 컴퓨터에서 프로그램 A를 실행 중인데, 프로그램 B도 실행하고 싶습니다. OS가 없다면 A가 끝날 때까지 기다려야 합니다. OS가 있으면 두 프로그램을 빠르게 번갈아 실행하여 동시에 돌아가는 것처럼 보이게 합니다. 이것이 CPU 스케줄링(5장)의 핵심 문제입니다.

시나리오 2 — 메모리 관리: 메모리가 4GB인 컴퓨터에서 프로그램 A가 2GB, B가 2GB, C가 1GB를 필요로 합니다. OS가 없다면 누군가 직접 메모리 영역을 나누고, 각 프로그램이 자기 영역만 쓰도록 감시해야 합니다. 한 프로그램의 버그가 다른 프로그램의 메모리를 덮어쓰면 전부 망가집니다. OS가 있으면 각 프로그램에게 독립적인 주소 공간을 제공하고, 물리 메모리가 부족하면 디스크의 스왑 영역을 활용합니다. 이것이 가상 메모리(9장)입니다.

시나리오 3 — 파일 관리: 두 프로그램이 같은 파일을 동시에 쓰려고 합니다. OS가 없다면 프로그램 A가 쓴 데이터 위에 프로그램 B가 덮어쓰면서 데이터가 뒤섞여 파일이 손상됩니다. OS가 있으면 파일 잠금(File Locking)과 접근 제어로 동시 접근을 안전하게 관리하고, 파일이라는 추상화로 디스크 블록의 물리적 위치를 사용자에게 완전히 숨깁니다. 이것이 파일 시스템(10장)입니다.

시나리오 4 — 장치 관리: 프린터에 출력을 보내려면 프린터 컨트롤러의 레지스터에 데이터를 한 바이트씩 써야 합니다. 어떤 레지스터에, 어떤 순서로, 어떤 타이밍에 써야 하는지는 프린터 모델마다 다릅니다. OS가 없다면 모든 프로그래머가 모든 프린트 모델의 사양을 알아야 합니다. OS는 디바이스 드라이버라는 계층을 두어 이 복잡성을 흡수합니다. 프로그래머는 write(fd, data, len) 하나면 됩니다.

정리하면, 운영체제가 하는 일은 결국 하드웨어의 복잡성을 가리고, 여러 프로그램이 안전하게 자원을 공유할 수 있게 하는 것입니다. 거대한 소프트웨어 생태계는 이 기반 위에서만 가능하며, 이것이 운영체제가 컴퓨터 과학의 핵심 과목인 이유입니다.


운영체제의 구성 요소

운영체제를 구성하는 주요 모듈을 큰 그림에서 한 번 짚어보겠습니다. 각 모듈은 이 교재의 개별 장에서 깊이 있게 다룹니다.

  • 프로세스 관리(3~6장): 프로그램의 실행 단위인 프로세스와 스레드를 생성·종료·스케줄링·동기화합니다.
  • 메모리 관리(8~9장): 물리 메모리를 가상 주소로 추상화하고, 페이징과 스와핑으로 한정된 메모리를 효율적으로 사용합니다.
  • 파일 시스템(10장): 디스크 블록을 파일과 디렉토리로 추상화하여 사용자에게 친숙한 인터페이스를 제공합니다.
  • I/O 관리(11장): 키보드, 디스크, 네트워크 카드 등 다양한 장치를 통일된 방식으로 다룹니다.
  • 보호와 보안(12장): 자원에 대한 접근을 제어하고, 시스템을 외부 공격으로부터 보호합니다.

이 구성 요소들은 독립적이지 않습니다. 프로세스가 생성되면 메모리가 할당되고, 파일을 열면 I/O가 발생하고, 모든 과정에서 보호 검사가 이루어집니다. OS를 공부할 때 각 주제를 따로 이해하면서도, 전체적으로 어떻게 맞물리는지를 놓치지 않는 것이 중요합니다.


개발자가 OS를 이해해야 하는 이유

프레임워크가 다 해주는데 왜 OS를 알아야 하나요?라는 질문은 매우 자연스럽습니다. Python으로 웹 서버를 만들 때 flask.run()만 호출하면 되는데, CPU 스케줄링이나 페이지 테이블을 왜 알아야 할까요?

답은 간단합니다. 프레임워크가 해결해주지 못하는 문제가 반드시 찾아오기 때문입니다. 아래는 실무에서 흔히 마주치는 상황들입니다.

상황 1 — 메모리 문제: 서버의 메모리 사용량이 배포 후 서서히 증가하여, 3일 뒤 OOM(Out of Memory) Killer가 프로세스를 강제 종료했습니다. 재시작하면 다시 3일 뒤 같은 현상이 반복됩니다. 이것이 메모리 누수인지, 정상적인 캐시 증가인지, 가비지 컬렉터 문제인지 판단하려면 프로세스의 메모리 구조(힙, 스택, 공유 라이브러리)와 가상 메모리, RSS vs VSZ의 차이를 이해해야 합니다.

상황 2 — 동시성 버그: 멀티스레드 코드에서 "가끔" 결과가 달라지는 버그가 보고되었습니다. 로그를 봐도 단서가 없고, 브레이크포인트를 걸면 재현이 되지 않습니다. 타이밍에 의존하는 경쟁 조건(Race Condition)이라는 동기화 문제입니다. 이 문제는 원리 자체를 모르면 디버깅이 불가능합니다. "내 코드에는 동기화 문제가 있을 수 있다"는 의심 자체가 OS 지식에서 출발합니다.

상황 3 — 성능 병목: 서버의 CPU 사용률은 20%인데 응답 시간이 느립니다. CPU가 바쁘지 않은데 왜 느릴까요? I/O 대기(디스크, 네트워크, 데이터베이스 응답) 때문입니다. top에서 wa(I/O wait) 열을 확인하고, iostat으로 디스크 이용률을 보고, ss로 네트워크 연결 상태를 파악하는 — 이 모든 진단 과정이 OS 개념 위에서 동작합니다.

상황 4 — 컨테이너 이해: Docker 컨테이너가 "격리된 환경"을 제공한다고 합니다만, 정확히 무엇을 격리하는 걸까요? 컨테이너 안에서 root이면 호스트에도 영향을 줄 수 있나요? 메모리 제한을 128MB로 설정했는데 OOM이 발생하면 호스트 전체가 영향 받나요? 이 질문들에 답하려면 OS의 네임스페이스, cgroup, 가상 파일 시스템을 이해해야 합니다.

상황 5 — 면접: 기술 면접에서 "프로세스와 스레드의 차이를 설명하세요", "가상 메모리란 무엇인가요?", "데드락의 4가지 조건은?"은 단골 질문입니다. 이 질문들은 단순 암기가 아니라 시스템 수준의 사고 능력을 평가합니다.

프레임워크는 정상 경로(happy path)에서는 충분합니다. 그러나 장애, 성능 문제, 보안 이슈 같은 비정상 경로에서는 프레임워크 아래를 들여다볼 수밖에 없습니다. OS 지식은 그 아래를 볼 수 있는 눈을 열어줍니다.


운영체제의 종류와 분류

운영체제는 목적과 환경에 따라 다양하게 분류됩니다.

범용 OS(General-Purpose OS): Windows, macOS, Linux처럼 다양한 응용 프로그램을 실행할 수 있는 OS입니다. 데스크톱과 서버 모두에 사용됩니다. 범용이라 해서 하나의 OS가 모든 환경에 최적인 것은 아닙니다. Linux는 서버에서 압도적이고, Windows는 데스크톱에서 점유율이 높습니다.

모바일 OS: Android, iOS처럼 스마트폰·태블릿에 최적화된 OS입니다. 터치 인터페이스, 배터리 관리, 앱 격리, 보안(앱 서명·샌드박스)이 핵심입니다. 내부적으로 Android는 Linux 커널, iOS는 Darwin 커널(BSD 계열) 위에 구축되어 있으므로, 범용 OS의 원리 위에서 동작합니다.

실시간 OS(Real-Time OS, RTOS): VxWorks, FreeRTOS, QNX처럼 정해진 시간 안에 반드시 작업을 완료해야 하는 환경을 위한 OS입니다. 자동차 ABS, 항공기 제어 시스템, 의료 장비, 공장 로봇에 사용됩니다. 일반 OS는 "평균적으로 빠르다"를 목표로 하지만, RTOS는 "최악의 경우에도 데드라인을 지킨다"를 보장합니다.

임베디드 OS: 리소스가 극도로 제한된 장치(IoT 센서, 가전 기기, 스마트워치)를 위한 OS입니다. 메모리 수 KB~수 MB, CPU 수십 MHz 환경에서 동작해야 합니다. Zephyr, Mbed OS 등이 있습니다.

이 교재에서는 주로 범용 OS(Linux를 중심으로)를 다루지만, 여기서 배우는 원리 — 프로세스, 메모리 관리, 스케줄링, 동기화 — 는 모든 OS에 공통됩니다. RTOS의 스케줄링도 같은 이론적 기반 위에 서 있고, 모바일 OS의 앱 관리도 프로세스 관리의 확장입니다.

다음 절에서는 운영체제가 어떻게 발전해 왔는지, 그 역사를 따라가면서 OS의 핵심 개념들이 왜 생겨났는지를 살펴보겠습니다.

목차