[OSTEP] 프로세스의 개념

kshired·2021년 7월 29일
0

프로세스의 개념

일반적으로 프로세스는 실행중인 프로그램으로 정의한다.

운영체제는 어떻게 무한대에 가까운 CPU가 존재하는 것과 같은 환상을 만드는가?

  • CPU를 가상화하여 이러한 환상을 만든다.
  • 하나의 프로세스를 실행하고, 얼마 후 중단 시키고 다른 프로세스를 실행하는 작업을 반복하면서 여러개의 가상 CPU가 존재하는 환상을 만든다.
  • 이러한 방식을 시분할( time-sharing )이라고 한다.
  • 시분할은 CPU를 공유하기 때문에, 프로세스의 성능은 낮아진다.

CPU 가상화의 효율적 구현을 위해서는 "도구"와 "지능"이 필요하다.

이 "도구"를 메커니즘이라고 부르는데, 메커니즘은 필요한 기능을 구현하는 방법이다.

"지능"은 정책(policy)의 형태로 나타난다.

정책은 운영체제가 결정을 내리는 데 사용되는 알고리즘이다.

ex) 다수의 실행가능한 프로그램이 존재할 때, 어느프로그램을 먼저 실행시키는가는 스케쥴링 정책이 정한다.

프로세스의 개념

  • 실행중인 프로그램
  • 하드웨어의 상태(machine state)를 이해해야 프로세스의 구성요소를 이해할 수 있다.
  • 프로세스가 접근할 수 있는 메모리는 프로세스를 구성하는 요소이다.
  • 레지스터도 프로세스의 하드웨어 상태를 구성하는 요소이다.
    • PC ( Program Counter ) : 프로그램의 어느 명령어가 실행중인지를 알려준다
    • Stack pointer와 Frame pointer는 함수의 변수와 리턴 주소를 저장하는 스택을 관리할 때 사용하는 장치이다.

프로세스 API

  • 생성 ( Create )
    • 새로운 프로세스를 생성하는 방법을 제공하는 API
  • 제거 ( Delete )
    • 프로세스를 강제로 제거할 수 있는 방법(사용자가 제거)을 제공하는 API
  • 대기 ( Wait )
    • 때때로 어떤 프로세스의 실행 중지를 기다릴 필요가 있기 때문에 제공하는 API
  • 각종 제어 ( Miscellaneous Control )
    • 프로세스 제거, 대기 이외에, 여러가지 제어 기능들이 제공되는 API.
    • 프로세스 일시정지, 일시정지 후 재개 등의 API
  • 상태 ( Status )
    • 프로세스 상태 정보를 얻어내는 API

프로세스 생성

  • 프로세스 생성을위해 운영체제는 처음으로, 프로그램 코드와 정적 데이터 ( static data, 초기값을 가지는 변수.. 등 ) 을 메모리, 프로세스의 주소 공간에 load한다.
  • 현대의 운영체제들은 프로그램을 실행하면서 필요할 때 필요한 부분만 메모리에 탑재한다.
  • 그 후, 특정 크기의 메모리 공간이 프로그램에 스택 용도로 할당되어야한다.
    • C에서는 지역 변수, 함수 인자, 리턴 주소등을 저장하기 위해 스택을 사용
    • 운영체제는 스택을 주어진 인자로 초기화 한다. ( main()의 argv 등을 이용 )
  • 운영체제는 프로그램의 을 위한 메모리 영역을 할당한다.
    • 힙은 동적으로 할당 된 데이터를 저장하기 위해 사용된다.
  • 운영체제는 STDIN, STOUT, STERR 등의 파일 디스크립터(file descriptor)와 관련 된 초기화 작업을 수행한다.
    • 이 부분은 영속성에서 설명

코드와 정적데이터 메모리에 탑재 → 스택과 힙을 생성 및 초기화 → 입출력 등의 셋업

→ 운영체제는 프로그램 실행을 위한 준비가 끝났다.

→ 프로그램이 시작된다.

프로세스 상태

  • 실행 ( Running )
    • 실행상태인 프로세스는 프로세서에서 실행중이다.
    • 프로세스는 명령어를 실행하고 있다.
  • 준비 ( Ready )
    • 프로세스는 실행할 준비가 되어있지만, 운영체제가 다른 프로세스를 실행하고 있는 등의 이유로 준비중이다
  • 대기 ( Blocked )
    • 프로세스가 다른 사건을 기다리는 동안 프로세스의 수행을 중단시키는 것.
    • ex) 디스크에 대한 I/O를 요청했을 때 끝날 때까지 대기 상태가 됨. 그동안 다른 프로세스들이 실행가능.

프로세스가 스케쥴되면 준비에서 실행상태로 전이되는 것.

실행상태에서 준비상태로 전이되는 것은 나중에 스케쥴 될 수 있다는 상태.

파일 입출력등의 이벤트가 발생하면 이벤트가 끝날 때까지 대기 상태로 전이.

대기가 끝나면 준비상태로 전이되고, 운영체제의 스케쥴링 정책에 따라 직후에 바로 실행 상태로 전이될 수 있다.

자료구조

  • 프로세스 상태를 파악하기 위해 프로세스들을 위한 프로세스 리스트(process list)와 같은 자료구조를 사용
  • 현재 실행중인 프로세스, 대기중인 프로세스를 위한 자료구조도 있음
  • register context 자료구조는 프로세스가 중단 되었을 때 해당 프로세스의 레지스터값을 저장한다.
    • 이 레지스터 값들을 복원하여 ( 실제 레지스터에 다시 저장함으로써 ) 프로세스 실행을 재개한다.
  • 운영 체제에 따라 프로세스 상태의 종류가 다른데, initial 상태를 가지는 시스템도 존재.
  • 프로세스는 종료되었지만, 해당 프로세스의 자원이 완전히 반납되지않은 final 상태도 있음 ( zombie 상태라고도 불림 )

숙제

RUN:CPU 는 1tick이 소요됨.

RUN:IO는 RUN + waiting*4 -> 5tick

  1. ./process-run.py -l 5:100, 5:100
CPU 이용률 예상 : 100%
총 Time 예상 : 5 + 5 -> 10

결과
Time     PID: 0     PID: 1        CPU        IOs
  1     RUN:cpu      READY          1
  2     RUN:cpu      READY          1
  3     RUN:cpu      READY          1
  4     RUN:cpu      READY          1
  5     RUN:cpu      READY          1
  6        DONE    RUN:cpu          1
  7        DONE    RUN:cpu          1
  8        DONE    RUN:cpu          1
  9        DONE    RUN:cpu          1
 10        DONE    RUN:cpu          1

Stats: Total Time 10
Stats: CPU Busy 10 (100.00%)
Stats: IO Busy  0 (0.00%)
  1. ./process-run.py -l 4:100, 1:0
두 프로세스가 모두 종료되는데 걸리는 시간 예상
: 4 + 6 -> 10

Time     PID: 0     PID: 1        CPU        IOs
  1     RUN:cpu      READY          1
  2     RUN:cpu      READY          1
  3     RUN:cpu      READY          1
  4     RUN:cpu      READY          1
  5        DONE     RUN:io          1
  6        DONE    WAITING                     1
  7        DONE    WAITING                     1
  8        DONE    WAITING                     1
  9        DONE    WAITING                     1
 10*       DONE       DONE

Stats: Total Time 10
Stats: CPU Busy 5 (50.00%)
Stats: IO Busy  4 (40.00%)
  1. ./process-run.py -l 1:0, 4:100
두 프로세스가 모두 종료되는데 걸리는 시간 예상
: 6
-> 첫 프로세스가 Block 되어있는 동안 두 번째 프로세스가 실행 될 것이라 예상.

Time     PID: 0     PID: 1        CPU        IOs
  1      RUN:io      READY          1
  2     WAITING    RUN:cpu          1          1
  3     WAITING    RUN:cpu          1          1
  4     WAITING    RUN:cpu          1          1
  5     WAITING    RUN:cpu          1          1
  6*       DONE       DONE

Stats: Total Time 6
Stats: CPU Busy 5 (83.33%)
Stats: IO Busy  4 (66.67%)
  1. ./process-run.py -l 1:0, 4:100 -c -S SWITCH_ON_END
두 프로세스가 모두 종료되는데 걸리는 시간 예상
: 9
-> -S SWITCH_ON_END는 IO가 끝날 때까지 기다림

Time     PID: 0     PID: 1        CPU        IOs
  1      RUN:io      READY          1
  2     WAITING      READY                     1
  3     WAITING      READY                     1
  4     WAITING      READY                     1
  5     WAITING      READY                     1
  6*       DONE    RUN:cpu          1
  7        DONE    RUN:cpu          1
  8        DONE    RUN:cpu          1
  9        DONE    RUN:cpu          1

Stats: Total Time 9
Stats: CPU Busy 5 (55.56%)
Stats: IO Busy  4 (44.44%)
  1. ./process-run.py -l 1:0, 4:100 -c SWITCH_ON_IO
두 프로세스가 모두 종료되는데 걸리는 시간 예상
: 6
-> -S SWITCH_ON_IO는 IO가 Block 되어있는 동안 다른 프로세스로 전환.

Time     PID: 0     PID: 1        CPU        IOs
  1      RUN:io      READY          1
  2     WAITING    RUN:cpu          1          1
  3     WAITING    RUN:cpu          1          1
  4     WAITING    RUN:cpu          1          1
  5     WAITING    RUN:cpu          1          1
  6*       DONE       DONE

Stats: Total Time 6
Stats: CPU Busy 5 (83.33%)
Stats: IO Busy  4 (66.67%)
  1. ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -I IO_RUN_LATER -c -p
모두 종료되는데 걸리는 시간 예상
: 예상 어려움
-> IO_RUN_LATER는 IO를 요청한 프로세스가 IO가 완료 됐을 때
그 후 바로 실행 될 필요 없음. 

Time     PID: 0     PID: 1     PID: 2     PID: 3        CPU        IOs
  1      RUN:io      READY      READY      READY          1
  2     WAITING    RUN:cpu      READY      READY          1          1
  3     WAITING    RUN:cpu      READY      READY          1          1
  4     WAITING    RUN:cpu      READY      READY          1          1
  5     WAITING    RUN:cpu      READY      READY          1          1
  6*      READY    RUN:cpu      READY      READY          1
  7       READY       DONE    RUN:cpu      READY          1
  8       READY       DONE    RUN:cpu      READY          1
  9       READY       DONE    RUN:cpu      READY          1
 10       READY       DONE    RUN:cpu      READY          1
 11       READY       DONE    RUN:cpu      READY          1
 12       READY       DONE       DONE    RUN:cpu          1
 13       READY       DONE       DONE    RUN:cpu          1
 14       READY       DONE       DONE    RUN:cpu          1
 15       READY       DONE       DONE    RUN:cpu          1
 16       READY       DONE       DONE    RUN:cpu          1
 17      RUN:io       DONE       DONE       DONE          1
 18     WAITING       DONE       DONE       DONE                     1
 19     WAITING       DONE       DONE       DONE                     1
 20     WAITING       DONE       DONE       DONE                     1
 21     WAITING       DONE       DONE       DONE                     1
 22*     RUN:io       DONE       DONE       DONE          1
 23     WAITING       DONE       DONE       DONE                     1
 24     WAITING       DONE       DONE       DONE                     1
 25     WAITING       DONE       DONE       DONE                     1
 26     WAITING       DONE       DONE       DONE                     1
 27*       DONE       DONE       DONE       DONE

Stats: Total Time 27
Stats: CPU Busy 18 (66.67%)
Stats: IO Busy  12 (44.44%)

첫 IO가 끝난 뒤, 다른 프로세서들이 실행되고 그 프로세서들이 끝날 때까지
기다렸다가 남은 두 번의 IO를 진행.
27번
  1. ./process-run.py -l 3:0,5:100,5:100,5:100 -S SWITCH_ON_IO -I IO_RUN_IMMEDIATE -c -p
모두 종료되는데 걸리는 시간 예상
: 16
-> IO_RUN_IMMEDIATE는 IO를 요청한 프로세스가 IO가 완료 됐을 때
그 후 바로 실행. 

Time     PID: 0     PID: 1     PID: 2     PID: 3        CPU        IOs
  1      RUN:io      READY      READY      READY          1
  2     WAITING    RUN:cpu      READY      READY          1          1
  3     WAITING    RUN:cpu      READY      READY          1          1
  4     WAITING    RUN:cpu      READY      READY          1          1
  5     WAITING    RUN:cpu      READY      READY          1          1
  6*     RUN:io      READY      READY      READY          1
  7     WAITING    RUN:cpu      READY      READY          1          1
  8     WAITING       DONE    RUN:cpu      READY          1          1
  9     WAITING       DONE    RUN:cpu      READY          1          1
 10     WAITING       DONE    RUN:cpu      READY          1          1
 11*     RUN:io       DONE      READY      READY          1
 12     WAITING       DONE    RUN:cpu      READY          1          1
 13     WAITING       DONE    RUN:cpu      READY          1          1
 14     WAITING       DONE       DONE    RUN:cpu          1          1
 15     WAITING       DONE       DONE    RUN:cpu          1          1
 16*       DONE       DONE       DONE    RUN:cpu          1
 17        DONE       DONE       DONE    RUN:cpu          1
 18        DONE       DONE       DONE    RUN:cpu          1

Stats: Total Time 18
Stats: CPU Busy 18 (100.00%)
Stats: IO Busy  12 (66.67%)

첫 IO가 끝나고 바로 바로 다음 IO들이 실행.
IO들이 block되는 동안 cpu 프로세스들이 실행 되어서 18 time.

아무 생각없이 block이 안된 run때도 된다고 생각했음;
profile
글 쓰는 개발자

0개의 댓글