Operating System Structure
운영 체제의 구조
사람들은 한 번에 한 가지 일을 하지 않는다.
일상적인 환경에서도
스포티파이로 음악을 들으며 카톡을 주고 받고
동시에 크롬으로 웹서핑을 하고
그마저도 크롬엔 3~4개 이상의 탭이 열려 있다.
일상적이지 않고 일하는 상황이더라도
엑셀을 켜두고 인터넷에서 검색을 하고 회사 자체 프로그램을 돌려
한 번에 여러가지 프로그램을 사용해야 한다.
사용할 때는 당연하다 생각되지만 사실은 그렇지 않다.
폰 노이만 구조에서 프로그램은 메모리에 올라가고
CPU는 이 메모리에서 데이터를 가져와 명령어를 처리하는데
컴퓨터가 얼마나 발전을 했든 하나의 CPU는 한 번에 하나의 일 밖에 처리를 하지 못한다.
그러나 작업의 효율성을 위해 컴퓨터는 여러 프로그램(Multiprogramming)을 가능케 해야 한다.
멀티프로그래밍
시스템 내 총 일들의 집합은 메모리에 보관된다.
멀티프로그래밍은 일(코드와 데이터)을 조직화하여 CPU가 항상 하나의 일을 실행할 수 있도록 한다.
CPU가 일을 처리할 때 다른 일은 기다려야 한다.
입출력을 예로 들면 입출력을 개시하면 인터럽트가 올 때까지 운영 체제가 다른 일로 바꾼다.
job scheduing 이 일을 선택하고 실행한다.
Multiprogramming 중인 컴퓨터의 메모리를 간단하게 나타낸 그림.
시분할(Timesharing)
시분할(Timesharing, 혹은 Multitasking)은 CPU가 하는 일을 자주 바꿔서
사용자들이 각각의 일을 하면서 일들과 상호작용할 수 있게 하는 기능이다.
이로써 interactive 한 컴퓨팅이 가능하다.
이때 반응 시간(response time)은 1초보다 작아야 한다. (엄청 빨라서 우리가 눈치 못채도록)
각 사용자는 메모리에서 실행되고 있는 최소 한 개의 프로그램을 가진다 => 프로세스
동시에 여러 일을 실행할 준비가 됐다면, 이 중 어떤 일을 택할지 선택해야 한다. => CPU 스케쥴링
프로세스들이 메모리에 맞지 않는다면 메모리로 다시 돌려보내고 나중에 자리가 나면 다시 올린다. => swapping
가상 메모리로 메모리를 다 채우지 않고 프로세스를 실행할 수 있다.
Operating-System Operations 운영 체제의 동작
운영 체제는 하드웨어의 인터럽트로 동작이 된다. (interrupt driven)
이 중 s/w의 인터럽트 중
0으로 나누는 등의 예외적인 상황은 exception, 운영 체제에게 일을 맡기는 것은 trap 으로 나뉜다.
dual-mode 동작은 운영 체제를 다른 시스템 요소와 자신에게서 보호한다.
운영 체제는 사용자 모드와 커널 모드로 나뉘는데,
이때 하드웨어가 제공하는 모드 비트로 구분한다. (0이면 커널, 1이면 사용자)
일부 명령어는 커널 모드에서만 실행이 가능하다.
사용자 모드에서 커널 모드로 전환될 때의 그림.
운영 체제의 특정 서비스가 필요해지면 trap 명령을 실행하여 운영 체제에게 도와달라고 신호를 보낸다.
관리자로서의 운영 체제
운영 체제는 컴퓨터의 운영을 위해 다음의 관리자 역할을 하기도 한다.
프로세스 관리자
프로세스는 작업의 단위이며 이는 자원을 필요로 한다.
자원은 hardware 를 가리키며 (CPU, memory, I/O device 등)
프로세스는 자원 사용의 주체이다.
프로세스는 실행 중인 프로그램을 말한다. 프로그램은 수동적이고, 프로세스는 능동적인 표현이다.
(passive entity, active entity)
프로세스는 일반적으로 여러 개가 실행이 된다.
이를 CPU가 multiplexing (multitasking 또는 multiprogram) 하는 것이다.
운영 체제는 프로세스를 관리하기 위해 다음의 동작들에 책임이 있다.
- 사용자 또는 시스템 프로세스를 생성하거나 삭제
- 프로세스를 연기하거나 재개
- 프로세스들의 동기화 작업에 대한 메카니즘
- 프로세스 간 통신 수단 제공
- 프로세스들의 교착 상태를 해결하는 메카니즘
메모리 관리자
모든 데이터는 프로세스 전이나 후나 메모리에 존재한다.
명령어가 실행되기 위해선 메모리에 존재해야 한다. (폰 노이만 구조)
메모리 관리자는 CPU의 활용과 사용자에게 보여지는 컴퓨터의 반응을 최적화 하기 위해
무엇이 메모리에 있는지 알아야 한다.
메모리 관리자는
- 어떤 프로세스가 메모리의 어느 부분을 사용하고 있는지를 추적해야 하고
- 어떤 프로세스(혹은 그 일부분)과 데이터가 메모리에서 들어오고 나가야 하는지를 결정하고
- 필요한 만큼 메모리 공간을 할당하거나 해제하여야 한다.
저장 공간 관리자
운영 체제는 정보의 저장에 대해 일관되고 논리적인 시각을 제시하여야 한다.
이때 논리적 저장 단위를 위한 추상적이고 물리적인 속성으로 file이 있다.
각 매체는 장치가 관리한다. (디스크 장치, 혹은 테이프 등의 저장 공간)
파일-시스템의 관리
파일은 대개 폴더별로 정리가 되어있다.
대부분의 시스템은 누가 어디에 접근할 수 있는지를 결정하는 접근 제어가 되어있다.
운영 체제는 이 시스템을 위해
- 파일과 폴더를 삭제하고 생성하며
- 파일과 폴더를 조작할 수 있으며
- 저장 장치의 특정 위치에 파일을 저장할 수 있고
- 비활성의 저장 장치에 안정적으로 백업파일을 만들 수 있어야 한다.
대용량 저장장치 관리자
대개 디스크는 메인 메모리에 들어가지 않거나
오래 저장되어야 하는 데이터를 저장하는데 쓰인다.
이를 적절히 관리하는 것은 매우 중요하다.
컴퓨터 동작의 전체적인 속도는 디스크의 하위 시스템과 그 알고리즘에 영향을 받는다.
즉 보조 기억 장치의 성능은 매우 중요하다.
내 어릴 때는 SSD가 상용화되기 전이었다.
아주 오래 전 우리 집에 아버지가 가지고 있던 플로피디스크를 본 기억이 날 정도이다.
즉 어릴 적 집의 pc는 운영 체제가 hdd에 저장되어 있었다.
옛날에 컴퓨터 인터넷 선은 모뎀 전화선으로 연결헤서
옆에 거실에서 할머니가 전화로 통화하면 인터넷이 안 되기도 하였다.
그 당시 만인의 운영 체제는 윈도우xp였고
우리 집 컴퓨터 바탕화면도 푸른 초원에 파란 하늘이었다.
그때 컴퓨터로는 이런 거나 하고 놀았다.
부팅 속도 역시 장난이 아니었는데
한 번 버튼 누르고 바탕화면 보는데까지 2~3분 기다렸어야 했고
바탕화면을 봐도 인터넷 켜는데 랙 없이 돌아갈 때까지는 추가로 또 몇 분 기다렸어야 했다.
버튼 한 번 누르고는 어디 가서 딴 짓 하다가 1~20분 보내고 돌아왔어야 한다.
지금도 그 말이 나오는지 모르겠는데
엄마들이 맨날 하는 말인
“집에 오자마자 컴퓨터부터 켜는…“은 사실 아들이 게임 중독이라서 그런 게 아니다.
그냥 그 시절 컴퓨터자 너무 느려서 그런 거고 아들이 시간 분배를 굉장히 잘하는 미래형 인간인 것이다.
그러다가 초등학교 고학년이었나 돼서 아버지가 새 컴퓨터를 구매하시면서
ssd라는 것을 샀고 그러면서 운영 체제도 윈도우 비스타로 바꿨다.
아버지는 게임을 좋아해서 그 새로 산 컴퓨터를 안방 TV랑 연결했다.
그때 처음으로 아버지 컴퓨터를 켰을 때의 기억은 아직까지도 남아있다.
부팅까지 몇 초 안 걸려서 바로 됐었고 인터넷도 바로 실행이 됐다.
당시 xp를 쓰는 세컨 컴퓨터는 굉장히 낡았던데다가
내가 켠 새 컴퓨터는 지금도 세련된 디자인으로 꼽히는 비스타를 썼고
또 디스플레이도 그냥 모니터가 아니라 40인치짜리 tv여서
굉장히 충격을 받았다.
아마 이때문에 SSD와 HDD의 성능 차이가 내 뇌리 속에 박힌 것일지도 모른다.
결론은, 보조 기억 장치의 성능은 컴퓨터 속도에 있어 진짜 굉장히 중요하다.
(물론 그걸 메모리로 올리는 메모리도 중요하다.)
또 옛날에는 디스크 조각 모음이라는 걸 했는데
아버지가 옛날에 그거 돌려놓고 컴퓨터 만지지 말라고 말씀하신 기억이 난다.
이게 ‘방 정리’랑 비슷한 건데
하드디스크는 암이 플래터를 고르고 돌리면서 헤드로 그 안에 섹터를 읽는 거라
이게 어디 저장되어 있느냐에 따라서 물리적인 한계로 시간이 더 들 수 밖에 없다.
그래서 한 프로그램이나 데이터를 여기저기 흩어지게 저장하면
그걸 읽을 때 왔다리 갔다리 하면서 읽으면서 어쩔 수 없이 시간이 더 들게 되는데
이를 방지하기 위해 컴퓨터를 쓰면서 흩어진 메모리를 다시 정리하는 작업이다.
이걸 하면 실제로 컴퓨터가 빨라졌다.
요즘은 하드디스크도 발전해서 이거는 잘 안 하는 것 같다.
옛날에 컴퓨터 켜면 보이는
빨간색 노란색 초록색 블록쌓기 아이콘이 기억이 난다.
참고로 서버의 dbms에서 varchar 같이 가변 문자 길이를 쓰게 되면
데이터의 수정 삭제가 일어나면서 저장 공간에 빈 공간이 생기게 되는데
새벽에 사람들이 잘 안 쓸 때 데이터를 다시 모아서 이 빈 공간을 메운다.
이 역시 성능을 위해서는 아니지만 대충 디스크 조각 모음이라고 비슷하다고 생각할 수 있다.
대용량 저장 공간을 관리하기 위해 메모리는
- 어느 곳이 비었는지 관리하고
- 빈 공간 중 어디에 할당할지를 정하고 (random access가 아니므로 위치마다 속도가 다르다.)
- 어떤 순서로 디스크를 읽을지를 정한다.
어떤 저장 공간은 딱히 빠를 필요는 없다.
2차 저장 공간 (하드 디스크 같은)이 아닌
광학 저장공간, 자기 테잎 같은 3차 저장 공간은
거기서 프로그램을 직접 돌리는 것도 아니라 엄청 빠를 필요는 없다.
하지만 이 역시 관리는 되어야 한다. 운영 체제나 다른 응용 프로그램이 관리한다.
왜 compiler가 register를 관리하냐면
코딩할 때 어셈블러 쓰는 거 아닌 이상
내가 변수 쓸 때 레지스터를 직접 지명하지 않는데
그걸 컴파일 할 때 컴파일러가 알아서 하기 때문이다.
자기테잎 빼고는 다 반도체로 만든다.
또한 특이한 점으로 메인 메모리와 보조 기억 장치는 다 운영 체제에게 관리 받는 것을 알 수 있다.
I/O 하위 시스템
운영 체제의 한 가지 목적은 사용자로부터 하드웨어의 특성을 숨기는 것이다.
예를 들어 내가 모니터를 필립스 27인치 걸 쓰든 LG 32인치를 쓰든
연결만 잘 하면 똑같이 돌아가야 한다는 말이다.
입출력 장치들이 어떻게 돌아가는지는 내 알 바 아니다.
하지만 역시 이것은 당연히 가능한 것이 아니다.
입출력 장치는 종류도 다양하고 그 종류마다 제조사가 많다.
그래서 관리도 다 각기 다르게 해줘야 한다.
또 입출력 장치들은 메모리를 사용하는데
이때 이 메모리도 관리해주어야 한다.
입출력을 관리하기 위한 입출력 하위 시스템은
- 입출력 중인 데이터를 임시로 저장하는 buffering
- 일부 데이터를 고속 저장 장치에 저장하는 caching
- 메모리에 저장 했다가 한 번에 보내는 spooling 등의 일을 수행한다.
그리고 특정 하드웨어 장치에 대한 드라이버가 필요하고
이것도 범용으로 쓰일 수 있게 범용 장치 드라이버 (general device driver) 인터페이스가 필요하다.
특정 장치에 상관 없이 입출력이 가능해야 한다.