운영체제(Operating System, OS)란 무엇인가
자원관리자(Resource Manager)라고 할 수 있다. 물리적인 자원(CPU, DRAM, Disk, Flash, Network)를 가상화 시켜서 더 효율적으로 자원을 관리할 수 있도록 해주는 시스템을 말한다.
운영체제와 커널(Kernel)의 용어에 대해서 헷갈릴 수 있는데, 커널은 항상 메모리에 상주해서 자원을 관리하는 것을 의미하고, 운영체제는 항상 메모리에 상주하지는 않는다. Linux 환경에서는 OS가 항상 메모리에 상주하기 때문에, Linux에서는 운영체제와 커널이 같다고 생각하면 된다.
운영체제의 역할
- 프로그램을 실행하기 쉽게 만들어 준다.
- 시스템을 올바르고 효율적이게 작동하도록 관리해준다.
운영체제의 추상화(Abstraction, Virtualization)
운영체제의 추상화는 물리적인 자원(Physical resources)들을 강력하고, 사용하기 쉽게 만들어 준다.
예를 들면, 가상 메모리를 사용해서 실제 메모리가 감당할 수 있는 양 보다 더 많은 크기의 프로그램을 메모리에 올릴 수 있도록 해주거나, 멀티테스킹, 동시성(concurrency) 기법을 사용해서 많은 프로세스들이 동시에 CPU를 사용할 수 있도록 해주는 역할 등이 있다.
이 추상화된 운영체제의 기능들을, 운영체제에서는 시스템 콜(System Call API) 을 제공해 사용자가 쉽게 사용할 수 있도록 도와준다.
시스템 콜(System Call)
운영체제에는 유저모드, 커널모드 두 가지 모드가 존재하는데, 유저 모드에서 시스템 콜이 호출이 되면, 시스템 콜 인터페이스를 통해 커널 모드로 전환이 된다. 이를 모드 스위치(Mode Switch) 라 하고, 운영체제는 커널모드에서 시스템 콜을 실행 시킨 후 다시 유저 모드로 돌아가게 된다.
각 분야 별 시스템 콜 예시는 다음과 같다.
- 프로세스 제어: fork(), exit(), wait(),
- 파일 관리: open(), read(), write(), close()
- 장치 관리: ioctl(), read(), write()
- 정보 유지: getpid(), alarm(), sleep()
- 보안(Protection): chmod(),umask(), chown()
CPU 가상화(Virtualizing CPU)
// cpu.c 파일
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <assert.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
if (argc != 2) {
fprintf(stderr, "usage: cpu <string>\n"); exit(1);
}
char *str = argv[1];
while (1) {
sleep(1);
printf("%s\n", str);
}
return 0;
}
위와 같은 프로그램을 CPU가 하나인 환경에서 쉘로 아래와 같이 실행해보면, 결과는 다음과 같다.
$ gcc -o cpu cpu.c -Wall
$ ./cpu A & ; ./cpu B & ; ./cpu C & ; ./cpu D &
[1] 7453
[2] 7354
[3] 7355
[4] 7356
A
B
D
C
A
B
...
쉘에서
&
은 프로그램을 background에서 돌리겠다는 뜻
실제로 CPU가 1개임에도 불구하고, 마치 여러개의 프로그램이 동시에 돌아가고 있는 듯한 착각을 불러일으킨다. 이를 CPU 가상화라 함.
메모리 가상화(Virtualizing Memory)
서로 다른 프로그램 두 개를 동시에 실행한 후 프로세스의 id를 주소를 출력해보면, 메모리의 주소가 똑같이 출력되는 경우가 있다. 이는 메모리 가상화를 이용했기 때문인데, 실제 물리적 메모리 주소는 다르지만 가상화 된 메모리 주소는 같을 수 있기 때문에 이렇게 출력되는 것이다.
메모리와 관련된 용어 정리
- TLB(Translation Lookaside Buffer): 가상 메모리 주소를 물리적인 메모리 주소로 변환할때 사용되는 캐시.
- page, segmentation: 메모리 가상화를 구현하는 방법
- NUMA(Non-Uniform Memory Access): 멀티 프로세서 시스템에서 사용되는 메모리 설계 방법 중 하나
동시성 문제( Concurrency )
같은 프로그램이나 시스템에서 동시에 뭔가를 하려 했을 때 생기는 문제들을 말한다.
예를 들어 서로 다른 두 개의 스레드가 같은 자원을 동시에 접근하려 했을 때(이를 race condition이라 한다), 하나의 스레드만 접근이 되는 경우가 있다. 이를 원자성(atomicity)라고 하는데, 이 원자성을 유지하기 위해 lock이 사용된다.
lock : 자원을 접근하기 전에 lock을 걸어놓고, 끝나면 unlock을 수행한다.
지속성(Persistence)
유저는 데이터를 영구적으로 유지하길 원한다. DRAM은 휘발성 이므로, 저장소(Disk,SSD 같은)에 데이터를 작성해 영구적으로 데이터를 유지하는 것을 지속성(Persistence)라고 한다.
운영체제 설계 목표
- 추상화(Abstraction): logic gate의 이해없이 프로그램을 만들 수 있도록 해주는 것
- 수행 능력(Performance): OS의 오버헤드를 최소화 시키는 것.
- 보안(Protection): 다른 프로세스가 또 다른 프로세스로 부터 독립되어 있어야 한다.
- 신뢰성(Reliablity)
- 그 외: Policy와 mechanism 분리
1. policy: 다음에 프로세스 수행을 어떻게 할거냐? 같은 것들, 무엇을 수행할 것인가?
2. mechanism: queue를 사용할거다, stack을 사용할거다 같은 것들, 어떻게 수행할 것인가?