티스토리 뷰

반응형

안녕하세요! Pingu입니다~

 

이번 글에서는 운영체제에서 Process라고 불리는 것에 대해 알아보려고 합니다. 제가 공부할 때 참고하고 있는 OSTEP 책에선Chapter 6 - Direct Execution부분입니다.

Limited Direct Execution

CPU를 가상화해야 하는 이유는 저번 글에서 알아봤습니다. 간단히 말하면 여러 개의 프로그램을 동시에 작동하기 위해 CPU 가상화가 필요했는데요, 이는 실제로는 Time Sharing기법으로 구현할 수 있었습니다. Time Sharing을 사용하여 CPU 가상화를 구현하려면 몇 가지 고려해야 할 점이 있습니다. 첫 번째는 Performance입니다. 시스템에서 가상화를 구현할 때 오버헤드 없이 구현하는 방법을 생각해야 합니다. 두 번째는 Control입니다. CPU에 대한 제어를 유지하면서 프로세스를 효율적으로 실행하는 방법을 생각해야 합니다. 여기서 제어란 접근 불가능한 리소스에 접근이 안되게 하는 등의 역할을 합니다. 즉 이번 글에서는 성능과 제어를 유지하면서 CPU 가상화를 구현하는 방법을 알아보려고 합니다.

Basic Technique: Limited Direct Execution

개발자들은 프로그램을 빠르게 실행되도록 하기 위해 Limited Direct Execution이라는 기술을 만들었습니다. 여기서 Limit를 뺀 Direct Execution은 프로그램을 한 번 수행하면 종료될 때까지 수행하는 방법입니다.

위의 표와 같이 한 번 실행하면 종료될 때까지 프로세스는 멈추지 않습니다. 하지만 이 방법으로는 지금 구현하려고 하는 CPU 가상화를 구현할 수 없습니다. 우선 한 번 실행된 프로세스에 대해 제어를 할 수 없으며 Time Sharing을 할 수 없습니다. 즉 이러한 방법에 어떠한 Limit를 줘야 CPU 가상화를 구현할 수 있게 됩니다! 그럼 이를 해결하기 위한 Limit를 살펴보도록 하겠습니다.

Problem #1: Restricted Operations

아까 본 문제점이 있던 Direct Execution은 빠르다는 장점은 있습니다. 하지만 실행 중 디스크에 대한 I/O 요청이나 CPU, Memory에서 더 많은 리소스를 요청하는 경우를 해결할 수 없기 때문에 사용할 수 없었습니다. 이를 해결하기 위한 방법에는 어떤 방법이 있을까요?

 

첫 번째 방법은 프로세스가 I/O 및 기타 작업들을 모두 수행하도록 하는 것입니다. 하지만 이렇게 하는 것은 바람직하지 못할 수 있는데, 예를 들어 파일에 대한 접근 권한을 부여하기 전에 권한을 확인하려고 하는 파일 시스템을 만든다고 생각해보겠습니다. 이때 프로세스가 디스크에 대한 I/O를 처리하게 설정해도 권한을 부여할 수는 없습니다. 만약 이를 허용한다면 프로세스가 디스크를 마음대로 접근할 수 있기 때문에 보호 기능이 손실되게 됩니다.

 

이러한 문제 때문에 실제 사용되는 방법은 프로세스를 User mode, Kernel mode로 상태를 구분하는 것입니다. User mode 상태에서는 수행할 수 있는 작업에 제한을 둬서 해당 작업을 수행하려고 하면 오류를 발생합니다. 이를 보완하기 위해 Kernel mode라는 OS가 실행되는 상태를 만들었고 I/O 요청과 같은 권한이 필요한 작업은 Kernel mode 상태에서 수행하게 됩니다.

 

하지만 만약 User mode의 프로세스가 Kernel mode에서 수행 가능한 작업을 원할 땐 어떻게 해야할까요? 이럴 때 사용하는게 system call입니다. System calluser mode 프로세스에게 kernel mode에서 수행가능한 작업을 수행할 수 있게 해 줍니다. System call이 실행되면 trap명령으로 권한을 바꿔 작업을 수행하고 수행 후엔 OS가 return-from-trap 명령으로 다시 원래의 권한으로 돌아옵니다.

 

Trap명령이 수행되면 프로세스는 program counter, flags, register 정보를 kernel stack에 넣습니다. 그런 뒤 return-from-trap 명령이 수행되면 이러한 데이터를 모두 제거합니다.

trap table 구조

이제 user mode에서 kernel modemode switch할 때 trap을 사용한다는 것도 알았습니다. 그렇다면 OS는 trap을 어떻게 사용할 수 있을까요? OS가 trap을 처리하기 위해선 위의 그림과 같은trap table이라는 것을 사용합니다. 이는 부팅할 때 초기화가 됩니다. Trap table에는 소프트웨어적 사건들을 처리하기 위한 함수가 들어있습니다. 또한 이러한 함수들에는 system-call number이라는 번호가 정의되어있고 위의 그림의 테이블을 사용한다고 가정했을 때, divide_by_zero()함수를 호출하고 싶다면 0을 전달하게 됩니다. 그럼 실제 프로세스가 trap을 사용하여 작업을 수행하는 과정을 살펴보겠습니다.

 

위와 그림과 같이 진행되며 trap table은 부팅할 때 OS가 생성합니다. 그 이후 프로세스가 생성되어 user mode에서 수행하다 system call이 발생하여 trap으로 kernal mode로 접근합니다. 해당 작업이 끝나면 다시 user mode로 돌아와 작업을 수행하고 작업이 끝나면 프로세스를 제거하게 됩니다.

 

Problem #2 Switching Between Processes

지금까지 알아본 Limited Direct Execution으로 하나의 프로세스가 수행되다 권한이 있는 작업을 수행하는 방법에 대해 알아봤습니다. 그렇다면 이젠 하나의 프로세스가 아닌 여러 개의 프로세스를 동시에 실행할 때 발생할 수 있는 문제를 해결하기 위한 방법을 알아보겠습니다!

 

CPU 가상화를 위한 방법으로 Time sharing방법이 있다고 했었습니다. 이 방법은 실제로 여러개의 프로세스가 동시에 실행되는 것이 아닌 사람은 느낄 수 없는 아주 짧은 시간 동안 프로세스들을 실행하여 마치 동시에 실행되고 있는 것처럼 보이게 하는 방법이었습니다.

 

위와 같이 time sharing 기법을 사용하여 프로세스들을 진행할 때 실행할 프로세스를 바꿀 때 OS가 제어권을 가져와 서 어떤 프로세스를 다음에 실행할지와 같은 부분을 제어해줘야 합니다. 이렇게 OS가 제어권을 가져오는 방법에는 2가지 방법이 있습니다. 첫 번째는 서로 협력하는 방법으로 system call을 사용하는 방법입니다. 프로세스가 system call을 발생하면 OS로 제어권이 넘어오게 되고 OS는 스케쥴링과 같은 작업을 수행 후 다음 프로세스에게 제어를 넘기면 됩니다. 하지만 이 방법은 만약 어떤 프로세스가 system call을 발생하지 않는다면 어떻게 될까요? 아마 OS에게 제어가 넘어오지 않는 상황이 발생할 수도 있을 것 같습니다. 이를 해결하기 위한 두 번째 방법은 time interrupt를 사용하는 것입니다.

 

자, 그럼 interrupt는 무엇일까요? 아까 trap은 소프트웨어적 사건이라고 했는데 interrupt는 하드웨어적 사건을 OS에게 알리는 메커니즘이라고 볼 수 있습니다. Interrupt를 처리하는 방법은 trap을 처리하는 방법과 유사합니다. Interrupt table에 다양한 interrupt를 처리하는 interrupt handler가 정의되어있고 이를 사용해 처리하게 됩니다. 그럼 아까 두 번째 방법으로 사용한다던 time interrupt를 알아보도록 하겠습니다. Time Interrupt는 일정 시간마다 interrupt를 발생시키는 방법입니다. 예를 들어 10ms동안 프로그램을 실행하고 다음 프로그램을 진행하려고 하는데 time interrupt는 1ms마다 발생한다고 가정해보겠습니다. 그럼 10번의 time interrupt가 발생되면 OS가 제어를 갖고 다음 프로세스를 실행하는 아주 간단한 아이디어입니다.

 

그럼 이제 실행되는 프로세스가 바뀔 때 OS에게 제어를 주는 방법도 알았습니다. 그럼 여러 개의 프로세스를 잘 수행할 수 있을까요? 아쉽게도 아직은 아닙니다. 아직 남은 문제점이 무엇인지 살펴보겠습니다!

 

만약 A, B 프로세스가 있다고 가정합니다. Time sharing기법으로 두 개의 프로세스를 번갈아 가며 실행하는데 A 프로세스를 실행하다 B 프로세스가 실행되고 다시 A 프로세스를 실행하려고 하는 경우 다시 처음부터 실행하는 것이 효율적일까요? 아니면 진행한 부분은 생략하고 그 이후부터 실행하는 것이 효율적일까요? 당연히 후자가 효율적입니다. 이렇게 프로세스의 정보를 기억했다 나중에 다시 실행될 때 사용하는 방법을 context switch라고 합니다. 여기서 context란 나중에 다시 실행될 때 사용될 프로세스에 대한 정보이고 하드웨어 register의 집합입니다.

 

Context switchcontext save, context restore라는 두 가지 작업으로 구성됩니다. 작업의 이름을 보면 바로 이해할 수 있듯이 하나는 context를 저장하는 것이고 하나는 복구하는 것입니다. Context save는 프로세스가 진행되다 다른 프로세스를 진행할 때 나중에 다시 실행되기 위해 정보를 저장하는 것이고 context restore는 프로세스가 다시 실행될 때 저장한 프로세스에 대한 정보로 복구하는 작업입니다. 참고로Context saveProcess Control Block이라는 구조로 저장되게 됩니다.

 

time interrupt 기법을 적용한 프로세스 실행과정

위의 그림은 time interrupt 기법을 적용한 프로세스 실행 과정입니다. 이 과정에서 부팅 시 interrupt tabletrap tabletrap table로 한 번에 처리하였고 time interrupt를 위한 interrupt timer를 실행해줍니다. A 프로세스가 실행되다 timer interrupt가 발생하여 레지스터에 context를 저장하고 프로세스 B의 context를 복구한 뒤 프로세스 B를 실행하게 됩니다. 물론 이렇게 진행되면 아주 복잡해 보이지만 아주 짧은 시간에 수행되기 때문에 사용자는 마치 두 개의 프로세스가 동시에 실행 중인 것처럼 보이게 됩니다.

 

어느 정도 이해가 되셨나요?? 저는 잘 이해가 안 되어 context switch 진행과정을 그림으로 그려봤습니다. 그림이 도움이 될까 해서 올려보겠습니다 ^~^

 

위와 같은 방식으로 진행되는 context switch도 시간이 걸리며 오버헤드가 발생하는 작업입니다. 그래서 하드웨어에서 context switch를 지원하는 hyper-threading라는 기술도 존재합니다.

 

위의 코드는 Context Switch가 수행되는 수도 코드를 나타낸 것입니다. 복잡해 보이지만 알고 보면 정말 간단한데요, 우선 코드가 Save, Load로 크게 나눠져 있습니다. Save는 CPU에 있는 데이터를 메모리로 옮기는 작업이고 Load는 메모리에 있는 데이터를 CPU로 옮기는 작업입니다. 아주 간단하죠?

Worried About Concurrency?

지금까지 CPU 가상화를 하기 위해 프로세스에서 발생하는 문제와 해결방법을 알아봤습니다. 근데 또 문제가 있을 수 있습니다. 문제가 계속 발생하네요 ㅠ.ㅠ 어쨌든 발생할 수 있는 문제는 하나의 interrupt를 처리 중에 다른 interrupt가 발생하면 누구를 먼저 처리할 지에 대한 문제, system call을 처리중 timer interrupt가 발생하면 어떤 것을 먼저 처리할지에 관한 문제가 되겠습니다.

이런 문제를 해결하는 방법에는 다음과 같은 방법이 있습니다.

 

  • Disable interrupt
    • 다른 인터럽트 처리 중일 때 발생하는 인터럽트는 무시하는 것이다.
  • Priority
    • interrupt에 우선순위를 줘서 순차적으로 처리한다.
  • Locking mechanism
    • Lock 기법을 사용하여 처리한다.

이러한 문제는 Concurrency단원에서 다시 다뤄보도록 하겠습니다!

마무리

이번 글에서는 Limited Direct Execution에 대해서 알아봤습니다. 직접 수행을 하는 것을 허용하지만 발생하는 문제를 처리하는 방법을 알아봤습니다. 프로세스가 권한이 있는 작업을 수행하고 싶을 때를 해결해주는 Mode switch, 프로세스들이 time sharing기법으로 실행될 때 프로세스의 정보를 기억하기 위한 context switch가 있었습니다!

 

읽어주셔서 감사합니다!

 

다음 글 : 프로세스를 스케줄링 하는 방법들

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함