공부/OS

[운영체제] 컨텍스트 스위칭은 언제 일어나야 하는가?

algosketch 2021. 4. 18. 11:28

컨텍스트 스위칭은 언제 일어나야 하는가?

다음 4 가지 경우가 있다.

  1. 프로세스가 CPU 를 양보하는 경우
  2. 프로세스가 시스템 API 를 호출하는 경우
  3. 프로세스가 I/O 를 요청하는 경우
  4. timer interrupt
  1. 프로세스가 자발적으로 CPU 를 포기하는 경우
    임베디드같이 프로세스를 적게 사용하는 경우 프로그래머가 조절해서 사용이 가능하다.
    하지만 고의 혹은 실수로 하나의 프로세스가 CPU 를 계속해서 차지하는 경우가 발생할 수 있다.
  2. 시스템 API 호출을 이용하는 경우
    시스템 API 호출 이후 다시 원래 프로세스로 돌아가는 것이 아니라 컨텍스트 스위칭을 시킨다.
    사용자 상호작용이 많은 경우 사용이 가능하다.
    문제점 : 시스템 API 를 호출하지 않는 프로그램의 경우 장기간 CPU 를 사용할 수 있다.
  3. I/O 요청시 컨텍스트 스위칭하는 경우
    I/O 를 기다릴 필요가 없으므로 I/O 요청이 발생하면 컨텍스트 스위칭한다. 2번과 유사하다.
    문제점 : 2번과 마찬가지로 I/O 요청이 없는 프로세스의 경우 장기간 CPU 를 사용할 가능성이 있다.
  4. timer interrupt 이용 (preemtive context switching)
    컨텍스트 스위칭이 발생할 필요가 없음에도 불구하고 일정 시간 CPU 를 사용했다면 컨텍스트 스위칭이 일어난다. 이것을 preemtive context switcing 이라고 한다. (프로세스 수행 중 포기하는 것을 preemtion 이라고 한다.) 그 일정 시간에 해당하는 용어는 scheduling quantum(스펠링 겁나 어려움 ㅡㅡ) 혹은 time slice 라고 부른다.
    문제점 : 소프트웨어가 아니라 하드웨어에서 타이머를 지원해야 한다. 다행히 현대의 CPU 는 대부분 타이머를 지원하고 여러 개의 타이머를 지원하는 경우도 있다.

process isolation

각각의 프로세스는 다른 프로세스로부터 독립적이어야 한다. 실수로라도 다른 프로세스의 메모리에 접근하는 등의 문제로부터 보호 받아야 한다.

일단 두 가지 접근 방법을 생각할 수 있다.

  1. interpreter
  2. simulator
  3. 인터프리터를 이용하는 방법은 한 줄 한 줄 컴파일 하면서 실행이 가능하면 실행하고, 불가능하면 어플리케이션을 멈춘다.
    simulator 를 이용하는 대표적인 예는 java 의 jvm 이다. 가상 머신을 사용할 경우 문제가 생겨도 가상 머신 내부에서만 문제가 생기고 실제 운영체제나 다른 프로세스에는 영향을 미치지 못 한다.
    이 두 가지 접근 방법은 느리다는 단점이 있다.

    운영체제는 프로세스가 실행할 수 있는 명령어와 실행이 불가능한 명령어는 나눈다.

protected mode

명령어의 위험도에 따라 ring 0 ~ 3 까지 정해지고 ring 0 은 kernel 이 사용하고 ring 3 은 user 가 사용한다. ring 1~2 는 디바이스와 관련된 것이다. 근데 대부분 ring 0 과 ring 3 만 사용한다고 한다. ring 3 은 userland 라고 부른다.
ring 0 에서는 모든 명령어를 실행할 수 있다. ring 3 에서는 특권 명령은 사용할 수 없고 만약 사용할 경우 general protection exception 이 발생하고 어플리케이션이 죽는다.

real vs protected

CPU 는 시작할 때 real 모드로 시작하며 real 모드에서는 모든 명령어 실행이 가능하다. 부트 로더에서 protected 모드로 바뀐다.

ring 3 을 사용하는 어플리케이션의 경우 ring 0 의 명령어를 사용할 수 없기 때문에 필요할 경우 int 0x80 을 발생시킨다. int 0x80 은 운영체제와 컨텍스트 스위칭이 일어나고 이것은 프로세스 컨텍스트 스위칭과 매우 유사하다.

mode transfer

  1. EIP, CS 등을 저장하고 모드를 ring 3 에서 ring 0 으로 바꾼다.
  2. 프로세스의 상태를 저장한다.
  3. eax 값을 읽어서 시스템 콜을 한다.
  4. 원래 프로세스를 복원한다.
  5. eax 값에 반환 값을 넣는다
  6. 원래 프로세스로 iret 하고 모드를 ring 3 로 변경한다.
  • 인천대학교 컴퓨터공학부 3학년 전공필수 과목인 박문주 교수님의 운영체제 강의를 듣고 작성한 글입니다.