OS는 전체 시스템이 정확하고 효율적으로 동작하게 하는 데에 책임이 있다.
모든 자원에 대한 책임을 갖고 syscall이 들어오면 그 자원을 가상화해서 user software에게 제공한다.
OS는 resource manager이다.
프로그램이 원하는 resource를 OS가 제공한다.
- virtualization
- concurrency
- persistence
소프트웨어가 모든 하드웨어 자원을 자기가 갖고 있다는 illusion을 제공하는 것이다.
프로그램이 system call이라는 interface를 이용해서 OS에게 자원을 요청하면 OS가 CPU, 메모리, 디스크와 각종 장치들을 제공한다.
ex. 메모리를 달라 -> malloc()
-> system call -> OS가 실제 메모리를 찾음 -> OS가 메모리를 virtual 형태로 만들어서 제공
CPU 자원을 통해 많은 프로그램이 동시에 동작하는(것처럼 보이는)데 각 프로세스에게 그 CPU를 자기가 온전히 소유한듯한 illusion을 제공해야한다.
시간을 쪼개서 주는 것이며 그 시간동안은 그 프로세스가 CPU를 혼자 사용하게 된다.
이것이 scheduling
이다.
메모리는 physical area에 존재하며 CPU보다 명확하고 쉽다.
자신의 memory space의 일부를 제공해주면 된다.
소프트웨어가 직접 메모리에 접근하도록 두면 마음대로 공간을 사용하다가 다른 프로세스의 공간을 침범하게 될 위험성이 생기므로 OS가 이를 관리한다.
이 때 사용하는 것이 address translation
이다.
OS는 자원을 정확하고 효율적으로 제공해야한다.
multi-thread 코드에서, 두 thread가 모두 volatile int counter
에 접근해 counter++;
를 수행한다면 loop의 크기가 작을 때는 첫 번째 thread가 실행되고 두 번째 thread가 실행되기 전에 첫 번째 thread의 수행이 끝나서 올바른 결과가 나올 수 있지만 loop의 크기가 커지면 두 thread가 실행되는 시간이 겹치면서 counter
에 접근하려고 한다 (race condition).
두 thread중 하나는 counter
의 값을 update하겠지만 둘 중 어느 thread가 값을 update했는지는 알 수 없다. 그냥 그 순간 scheduling된 thread가 counter
의 값을 update하는 것이다.
race condition을 방지하기 위해 locking과 같은 메커니즘을 사용하며 이것이 concurrency에 해당한다.
위의 경우에 race condition이 발생하는 이유는 ++
가 atomic하지 않기 때문이다.
어떤 instruction이 atomic하다는 것은 그 instruction이 실행되는 여러 step 사이에 그 무엇도 끼어들 수 없는 것을 의미한다. atomic하게 만들기 위해 mutex같은 것을 사용해야 한다.
소프트웨어는 자신의 data를 non-volatile memory에 저장하고 싶어한다. OS가 물리적 공간을 어떻게 다루는지와 file system등에 대해서 배운다.
file system은 디렉토리와 파일로 구성되어 있다.
user는 file system을 통해 raw disk에 접근함.. user는 원래 raw disk에 직접 접근할 수 없어야 한다(지금은 가능한 것도 많지만).
그리고 user가 file system을 이용할 때는 syscall을 사용하는 것 같다..
OS가 resource를 정확하게 제공하면 user program은 이를 걱정할 필요가 없어진다.