Uniprogramming과 Mutiprograming의 차이점 그리고 Mutiprogramming의 문제점에 대해서 간략하게 알아보자.
위의 그림을 통해 Uniprogramming일 때와 Multiprogramming일 때의 자원 사용률을 알아보자.
- Process use(CPU 사용률)
Uni:
Multi:- Memory use, Disk use, Printer use 모두 같이 계산한다.
- Elapsed time: 총 실행 시간
- Throughput: 단위시간당 처리된 job 수(1h)
- Mean response time: 응답시간
Uni:
Multi:
Multiprogramming에선 CPU 사용률(process use)을 최대화하는 것이 목표였는데, 이후 응답시간을 최소화하는 것을 더 중요하게 여겨 Time sharing 형식의 운영체제로 발전하였다. Multiprogramming 방식의 운영체제는 예를들어, I/O에 의해 job이 중단 될때 다른 job으로 바뀌었지만, Time Sharing 방식은 time slice(200ms)를 기준으로 job을 바꾸는 방식이다.
사용자들이 하나의 기계를 사용할 수 있게 하는 터미널도 존재했다. 이 사용자들은 하나의 기계의 CPU를 사용할 때, Time sharing 형태의 process switch가 일어났다.
이 때 process가 전환될 때 time slice가 모두 끝나 OS가 process를 중단(자원을 회수, preemption)하고 다음 process를 수행한다.
다른 자원들은 자원을 얻기 위해 기다려야하고 이 장소가 ready list(run queue)이다.
여기서 가장 적절한 프로세스를 선택하는 작업을 Scheduling이라 하고, 초기의 방식은 Round-robin이다.
(참고로 이 기계에 많은 유저들이 개인적인 정보를 저장하여, 이에 대한 파일 구조 시스템이 필요하게 되었다.)
Average response time = (0+1)/2 = 0.5 // 바로 응답하는 시간
Average turnaround time = (8+4)/2 = 6 // 실행이 전부 끝나는 시간
프로세스란 실행 중이거나 실행 가능한 프로그램이다.
프로세스는 큰 틀로 세 가지로 이루어져있으며 이는 데이터(data section), 실행가능한 프로그램(소스코드, Program section), 그리고 Execution Context(운영체제가 process를 제어하기 위한 메타데이터)이다.
Execution Context는 OS가 process를 제어할 수 있는 내부 데이터이다. 이 중 하나가 Register context(hardware context, 레지스터 정보)이며, 프로세스의 정보(instruction 또는 프로세스 데이터)를 저장한다.
(프로세스의 우선순위, I/O를 어떤 프로세스가 기다리는 지 등의 정보도 포함된다.)
long-term scheduler란 시스템 단위에서 받아들일 수 있는 프로세스를 저장하는 자료구조이다. short-term scheduler란 CPU 단위에서 할당할 프로세스들을 저장하는 자료구조이다.
자원 할당과 스케줄링을 위해 고려해야할 요건은 다음과 같다.
Fairness: 자원을 할당할 때, 공평하게 나눔
Efficiency: 쓰루풋을 최대화하고, 응답시간을 최소화함(Efficiency와 trade off 관계)
Differential responsiveness: 프로세스의 가중치마다 공정하게 자원을 분배(나중에 자세히 뱅움)
여러 개의 process가 많다면 메모리의 공간이 부족할 수 있다. 이에 대한 해결책은 virtual memory이다. Paging(고정 크기 조각으로 나눔)을 사용하여 필요한 부분만 분산적으로 메인 메모리에 로드한다. 그럼 실제로 물리적 크기보다 더 큰 프로그램을 실행할 수 있는 것처럼 느껴진다.
메모리에 분산적, 부분적으로 프로그램이 로드된 것을 볼 수 있다.
프로그램의 특정 page가 필요할 때 디스크에 있는 page를 메모리에 로드하는 것을 page fault라 칭한다.
I/O와 같은 시스템 자원을 보호하기 위해 user 모드에서 접근할 수 없도록 하였다. 이를 위해 커널 모드로 OS procedure call을 통해 안전하게(자원을 보호) 접근해야한다.
커널 모드로 전환하기 위해 systemm call이 필요하여 이는 user 모드에서 kernel 모드의 동작을 하기위한 interface이다.
시스템 콜은 컴퓨터의 자원을 사용하는 것이기 때문에, 굉장히 어렵다. 이를 위해 library를 사용해야 하며 이는 system call의 Higher API이다.(printf는 결국 system call write를 감싸고 있다.)
커널모드로 들어가기 위한 방법은 세 가지이다.(Interrupt, Exception, System call)
int 0x80 -> system call, 0x04 -> system call write
API는 레지스터를 통해서 시스템 콜에 필요한 데이터(파라미터)를 전달하고 호출까지만 한다.
또는 메모리에 파라미터를 블락단위로 저장하고 이의 주소를 레지스터에 저장한다.