우선 운영체제는 컴퓨터의 하드웨어와 소프트웨어 자원을 효율적으로 관리하고, 사용자가 컴퓨터를 편리하게 사용할 수 있도록 인터페이스를 제공하는 시스템 소프트웨어이다.
이를 좀 더 풀어서 설명하면, 운영체제는 컴퓨터의 관리자
역할을 한다. 프로세스들이 CPU를 어떻게 나눠 쓸지 결정하고, 제한된 메모리를 효율적으로 할당하며, 파일들을 체계적으로 저장하고 관리한다.
운영체제는 크게 커널(Kernel)과 시스템 프로그램으로 구성된다. 그 중에서도 커널이 운영체제의 핵심으로 여러 주요 기능을 수행한다.
프로세스 관리는 운영체제의 가장 핵심적인 기능.
프로세스란, 실행 중인 프로그램을 의미하는데(프로그램이 메모리에 로드되어 실행되는 동적인 개체) 운영체제는 이 프로세스들을 생성하고 관리하는 역할을 수행한다.
프로세스 관리의 주요 역할을 살펴보면, 우선 프로세스의 생명주기를 관리한다. 프로세스는 생성되고(Created), 실행 준비 상태가 되며(Ready), 실제로 실행되고(Running), 때로는 입출력을 기다리거나(Waiting), 마지막으로 종료(Terminated)된다.
-> 운영체제는 이러한 프로세스의 상태 변화를 추적하고 관리한다.
CPU 스케줄링도 프로세스 관리의 중요한 부분이다. 컴퓨터에서는 여러 프로세스가 동시에 실행되는 것처럼 보이지만, 실제로는 CPU가 매우 빠른 속도로 프로세스들을 번갈아가며 실행하는 것이다. 운영체제는 어떤 프로세스에 CPU를 할당할지, 얼마나 오래 실행할지를 결정한다.
프로세스들은 또한 협력해야 할 때가 있다. 이를 위해 운영체제는 프로세스 간 통신(IPC : Inter-Process Communication)을 지원한다.
예를 들어, 웹 브라우저에서 다운로드 관리자로 파일 정보를 전달하는 것도 IPC를 통해 이루어진다.
동기화도 중요한 기능이다. 여러 프로세스가 같은 자원을 사용하려 할 때(경쟁상태 : Race Condition) 문제가 발생할 수 있다. 마치 한 프린터로 여러 사람이 동시에 출력하는 것과 비슷한데, 운영체제는 세마포어나 뮤텍스 같은 동기화 도구를 제공하여 이런 문제를 해결한다.
마지막으로, 교착상태(데드락) 관리도 있다. 교착상태는 두 프로세스가 서로가 가진 자원을 기다리며 영원히 진행되지 못하는 상황을 말한다. 운영체제는 이러한 상황을 예방하거나 감지하고 해결하는 역할을 한다.
이러한 모든 기능들은 프로세스 제어 블록(PCB)이라는 자료구조를 통해 관리된다. PCB는 각 프로세스의 상태(실행, 준비, 대기 등), 카운터(다음 실행할 명령어의 위치), 레지스터 값 등 중요한 정보를 담고 있어서 운영체제가 프로세스를 효율적으로 관리할 수 있게 해준다.
프로세스 관리에는 스레드 관리도 포함된다. 스레드는 프로세스 내에서 실제로 작업을 수행하는 주체로, 하나의 프로세스는 최소 하나의 스레드(메인 스레드)를 가진다. 프로세스가 작업 공간이라면 스레드는 그 안에서 실제로 일하는 일꾼이라고 볼 수 있다.
예를 들어 워드 프로세서에서는 한 스레드가 키보드 입력을 처리하고, 다른 스레드는 맞춤법을 검사하며, 또 다른 스레드는 자동 저장을 담당하는 식으로 하나의 프로세스 안에서 여러 작업이 동시에 진행될 수 있다. -> 이처럼 하나의 프로세스 안에서 여러 작업이 동시에 진행될 수 있는 것은 멀티스레드 덕분
운영체제는 이러한 스레드들을 두 가지 수준에서 관리한다:
사용자 수준 스레드: 라이브러리를 통해 구현되며 운영체제는 이 스레드의 존재를 모른다. 스레드 전환이 빠르고 유연하지만, 한 스레드가 블록되면 전체 프로세스가 블록될 수 있다. (전체 블록되는 이유는 운영체제의 관점에서 볼 때 프로세스 단위로만 CPU 시간을 할당하기 때문. 운영체제는 사용자 수준 스레드의 존재를 모르기 때문에 한 스레드가 I/O 작업(컴퓨터가 외부와 데이터를 주고받는 모든 작업) 같은 블로킹 시스템 콜을 호출하면 운영체제는 해당 프로세스 전체를 블록 상태로 전환한다.)
-> 위에서 말하는 블록(Block)이란, 블록된다는 것은 프로세스나 스레드가 일시적으로 실행을 멈추고 대기 상태가 되는 것을 의미. 이 상태에서는 CPU를 사용할 수 없고, 어떤 조건이 만족될 때까지 기다려야 한다.
커널 수준 스레드: 운영체제가 직접 스레드를 관리한다. 한 스레드가 블록되어도 다른 스레드는 계속 실행될 수 있지만, 스레드 전환에 더 많은 시간이 소요된다. (커널 수준 스레드는 운영체제가 직접 관리하므로, 각 스레드를 독립적인 실행단위로 인식할 수 있음. 따라서 한 스레드가 블록되더라도 운영체제는 해당 스레드만 블록 상태로 전환. 다른 스레드에게 CPU 시간을 계속 할당 가능하다. -> 결과적으로 전체 프로세스의 작업이 계속 진행될 수 있음)
스레드는 같은 프로세스 내의 다른 스레드들과 코드, 데이터, 파일 등의 자원을 공유하면서도, 각자 독립적인 스택과 레지스터를 가진다. 이러한 특성 때문에 멀티스레딩은 자원을 효율적으로 사용하면서도 병렬 처리가 가능하게 한다.
메모리 관리 역시 운영체제의 주요 기능.
메모리 관리를 설명하기 전에, 먼저 메모리가 왜 중요한지 이해할 필요가 있다. 프로그램이 실행되려면 반드시 메모리에 적재되어야 하고, 프로세스가 작업을 수행하는 동안 필요한 데이터도 모두 메모리에 있어야 한다.
운영체제의 메모리 관리는
첫째, 각 프로세스에게 필요한 메모리 공간을 할당한다. 이때 메모리는 크게 네 가지 영역으로 나뉨.
둘째, 가상 메모리 시스템을 운영한다. 실제 물리적인 메모리보다 더 큰 메모리 공간을 제공하는 것처럼 보이게 하는 기술.
컴퓨터에서 실행되는 프로그램들은 점점 더 많은 메모리를 필요로 함 -> 하지만 물리적 메모리(RAM)는 한정되어 있고 비용도 많이 든다. 이런 상황에서 가상 메모리는 마치 실제 메모리가 더 큰 것처럼 보이게 만들어주는 기술.
프로그램이 사용하는 메모리 주소를 가상 주소
라고 하고, 실제 물리적 메모리의 주소를 물리 주소
라고 한다. 운영체제는 이 두 주소 체계 사이의 변환을 관리한다. 이때 페이징 기법을 사용하는데, 메모리를 동일한 크기의 작은 단위(페이지)로 나누어 관리하는 것.
실제 작동 과정으로 예를 들면, 4GB의 프로그램을 실행하는데 실제 RAM은 2GB밖에 없다고 가정. 이 경우 가상 메모리 시스템은
페이지 폴트
라고 한다.페이지 아웃
이라고 한다.이런 방식으로 가상 메모리는 두 가지 중요한 이점을 제공한다.
첫째, 물리적 메모리보다 큰 프로그램도 실행할 수 있게 된다. 전체 프로그램이 한꺼번에 메모리에 있을 필요가 없기 때문.
둘째, 여러 프로그램이 동시에 실행될 때도 메모리를 효율적으로 사용할 수 있다. 각 프로그램의 당장 필요한 부분만 메모리에 유지하면 되기 때문.
하지만 가상 메모리에도 단점이 있다. 하드디스크는 메모리(RAM)보다 훨씬 느리기 때문에 페이지 폴트가 자주 발생하면 성능이 크게 저하될 수 있음 -> 이를 스레싱(Thrashing)
이라고 하며, 운영체제는 이를 방지하기 위해 다양한 페이지 교체 알고리즘을 사용.
파일 시스템은 컴퓨터에서 데이터를 저장하고 관리하는 방식의 기초가 되는 중요한 부분
파일 시스템을 이해하기 전에, 왜 파일 시스템이 필요한지 생각해보자. 컴퓨터에서 모든 데이터는 결국 하드디스크나 SSD 같은 저장장치에 보관되어야 한다. 하지만 이 저장 장치는 단순히 0과 1비트들을 저장할 수 있을 뿐. 이 비트들을 의미 있는 정보로 구성하고, 쉽게 찾고 관리할 수 있게 만드는 것이 바로 파일 시스템의 역할이다.
파일 시스템은 데이터를 파일이라는 단위로 관리하고, 이 파일들을 디렉토리(폴더)를 통해 체계적으로 구성한다.
파일 관리에서 운영체제는 각 파일에 대해 여러 가지 정보를 관리한다. 파일의 이름, 크기, 생성 날짜, 수정 날짜, 접근 권한 등이 여기에 포함되어 있음. 이러한 정보들을 파일의 메타데이터라고 하며, 파일 시스템에서 특정 영역에 저장된다.
캐싱은 파일 시스템의 성능을 크게 향상시키는 중요한 메커니즘. 디스크는 메모리에 비해 매우 느리기 때문에, 자주 사용되는 데이터를 메모리에 임시로 보관하여 빠르게 접근할 수 있게 한다. 예를 들어, 문서를 편집할 때 파일의 내용이 메모리에 캐시되어 있어서 매번 디스크에서 읽어올 필요가 없다.
운영체제는 버퍼 캐시
와 페이지 캐시
라는 두 가지 주요 캐싱 메커니즘을 사용. 이들은 각각 다른 방식으로 성능 향상에 기여한다.
버퍼 캐시
는 디스크의 블록 단위(하드디스크나 SSD와 같은 저장 장치는 데이터를 저장할 때 가장 작은 단위로 블록
이라는 것을 사용)로 데이터를 캐시한다. 예를 들어 파일의 디렉토리 정보나 파일 시스템의 메타데이터를 메모리에 보관한다. 이는 마치 도서관에서 자주 찾는 책의 위치 정보를 메모장에 적어두는 것과 비슷하다고 생각하면 된다. 디스크에서 이러한 정보를 매번 읽어올 필요가 없어 시스템의 반응 속도가 빨라짐.
페이지 캐시
는 실제 파일의 내용을 캐시한다. 예를 들어 여러분이 문서 파일을 열면, 그 내용이 페이지 캐시에 저장된다. 같은 파일을 다시 열 때는 디스크에서 읽지 않고 메모리에서 바로 가져올 수 있음.
운영체제는 'LRU(Least Recently Used)'와 같은 알고리즘을 사용하여 캐시를 관리한다 -> 메모리 공간이 부족해지면, 가장 오랫동안 사용하지 않은 데이터를 캐시에서 제거한다. 또한 파일에 변경사항이 있을 때는 지연 쓰기(delayed write)
기법을 사용하여, 여러 변경사항을 모아서 한 번에 디스크에 기록함으로써 성능을 최적화한다.
이러한 캐싱 메커니즘 덕분에 파일 시스템은 느린 디스크 접근을 최소화하고, 빠른 메모리 접근을 최대한 활용할 수 있게 됨. 결과적으로 사용자는 파일 작업을 훨씬 빠르게 수행할 수 있다.
운영체제의 디바이스 관리는 컴퓨터에 연결된 모든 하드웨어 장치들을 효율적으로 제어하고 관리하는 핵심 기능.
-> 키보드, 마우스, 프린터와 같은 입출력 장치부터 하드디스크, 네트워크 카드까지 모든 장치가 관리 대상이다.
디바이스 관리는 세 가지 주요 메커니즘을 통해 이루어진다.
첫 번째는 디바이스 드라이버. 디바이스 드라이버는 운영체제와 하드웨어 장치 사이의 통역사 역할. 각 장치마다 고유한 명령어와 통신 방식 -> 디바이스 드라이버는 이를 운영체제가 이해할 수 있는 표준화된 방식으로 변환.
두 번째는 인터럽트 처리.
인터럽트는 장치가 운영체제에 자신의 상태나 요청을 알리는 신호. 예를 들어 사용자가 키보드를 누르면, 키보드는 인터럽트를 발생시켜 운영체제에 입력 있음을 알린다. 운영체제는 이러한 인터럽트를 감지하고 적절히 처리함으로써, 여러 장치들의 요청을 효율적으로 관리할 수 있다.
세 번째는 버퍼링과 스풀링이다.
이는 속도가 다른 장치들 사이의 데이터 전송을 원활하게 만드는 기술. 버퍼링은 데이터를 임시로 저장하는 공간을 제공하여 장치 간 속도 차이를 조절한다. 스풀링은 특히 프린터와 같은 느린 출력 장치를 위한 기술로, 출력할 데이터를 임시 저장소에 보관했다가 장치가 처리할 수 있는 속도로 전송한다.
이 덕분에 여러 프로그램이 동시에 장치를 사용하더라도 충돌없이 원활하게 작동할 수 있게 된다.