ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Operating System: Process (Chapter 4)
    공부하는 글른 2022. 3. 7. 18:44

    논문자격 시험 때문에 갑자기 추억의(?) Operating System 공부 자료를 뒤적거리게 된 겸 핵심만 모아서 블로그에 정리 해 봅니다. (bullet point 위주의.. 상당히 간결한 정리가 될 것 같습니다) 

    Process란

    • Process는 program을 담는 그릇이다.
    • OS가 process를 관리한다면, process는 program을 관리한다.
    • Process는 text section, stack, data section, heap으로 구성된다.  
      • text section: program code
      • stack: local variable, parameter, return address 등을 저장 (유지되지 않음)
      • data section: global variable, static variable 등을 저장 (유지됨)
      • heap: 동적 할당을 위한 공간. 가장 다루기 까다로움. symantic에 따라서 차지하는 memory가 다변

    • Process가 memory에 올라갈 때의 주소 공간은 위와 같이 생겼다. 
      • Stack과 Heap 영역이 서로를 바라보면서 증가하는데, 이로 인한 장점은 다음과 같다. 
        • Heap이 data section을 침범하지 않음
        • Stack이 다른 process memory 영역을 침범하지 않음

    Process State

    • Process의 state는 총 다섯 가지로 이루어진다. 
      • New: 새로운 process가 이제 막 생김
      • Running: CPU 배정 받아서 열심히 intruction을 실행하는 상태 
      • Waiting: 특정 event의 발생을 기다리는 상태. CPU 배정 받아도 실행 시킬 수 없음
      • Ready: CPU를 배정 받으면 실행이 가능한데, CPU를 기다리고 있는 상태
      • Terminated: 모든 execution이 종료된 상태. 다만 아직 process가 memory에서 내려오진 않은 상태
    • Diagram of Process state
      • Admitted: New state의 process가 Ready state로 넘어감
      • Scheduler dispatch: CPU scheduler에 의해서 Ready state에 있던 process에게 CPU가 배정됨. 따라서 Running state로 넘어감
      • Interrupt: Running state에 있던 process가 timer interrupt에 의해서 CPU를 빼앗김. 다시 Ready state로 넘어감
      • I/O or event wait: Running state의 process에서 I/O 가 발생하면 CPU를 빼앗고, Waiting state로 넘어감 
        • I/O interruption이 발생했을 때 Ready state가 아닌 Waiting state로 가는 이유: Ready state의 정의는 CPU를 할당받는 즉시 다시 바로 일을 수행할 수 있음을 의미. I/O interruption이 발생한 경우, CPU를 다시 줘도 즉각 일을 수행할 수 없기 때문에, 별도의 Waiting state를 만들어서 거기서 대기 시키는 것. 
      • Exit: 모든 execution이 완료됨 

    Process Control Block (PCB)란

    • Program을 돌리기 위해 필요한 모든 정보를 담은 것으로 process의 실체이다. 
    • Kernel data structure 중 하나 
    • Process state, Program counter, CPU registers, CPU scheduling information, Memory management information, Accounting infromation (Process가 얼마나 돌았는가), I/O status information (접근 중인 I/O device 정보) 등을 담고 있다. 
    더보기

    여기서부터는 좀 딥하니까... 

     

    Kernel data structure 안에 이 모든 정보를 다 담고 있지는 않는다. 단지 이 정보를 가리키는 Pointer 들이 존재한다. Kernel도 일종의 process라서 kernel의 stack, heap, data section 등의 address space를 갖고 있다. 일반 process (user process)의 stack에는 해당 process를 실행 시키기 위한 정보가 담겨 있는 반면, Kernel process의 stack에는 user process를 실행시키기 위한 정보를 저장한다. 

    이렇게 디자인하는 이유는 하드웨어를 사용하기 위함이다. Process0에서 Process1로 넘어가면서 0의 상태를 저장하고 1의 상태를 reload하는 작업들이 program code로 돌아가면, 엄청나게 많은 read & write가 발생한다. 이러한 process 간의 전환을 우리는 Context Switch라고 부르는데, program code로 돌아갈 경우, contex switch에 의한 overhead가 엄청 커진다. 따라서 response time이 중요한 multitasking system을 지원하기 위해서는 context switch의 overhead를 줄일 필요가 있다. 이를 위하여, context switch를 하드웨어적으로 지원해 주자는 아이디어가 나왔고, CPU가 하드웨어적으로 process switch를 엄청나게 빠른 속도로 처리 해 준다. 

    이때, kernel은 매우 고귀한(?) 영역으로, 감히 user process의 data를 담고 싶지 않다. (정확히는 신뢰하지 못한다) 따라서 믿을 수 있는 안전한 kernel 영역에는 user process의 memory 를 저장하고, 해당 user process의 PCB에서 Pointer를 통해 user process의 memory에 접근한다. 

    • CPU switch from Process to Process
      • P0가 실행되던 중, interrupt나 system call에 의해서 P1으로 CPU가 할당되는 상황을 설명 해 보자
        • P0의 상태를 PCB0에 저장한다
        • P1의 상태를 PCB1에서 읽어와서 reload한다
        • P1을 실행 시킨다
      • 이때 다시 interrupt나 system call에 의해 P0로 CPU가 할당된다면
        • P1의 상태를 PCB1에 저장한다
        • 저장해 뒀던P0의 상태를 PCB0로부터 reload한다
        • P0를 실행시킨다

    Process Scheduling Queue

    • Process state의 전이는 Queue에서 Queue로 이루어진다
    • Queue에는 모든 process들이 모여있는데, 정확히는 그 process를 가리키는 PCB를 가리키는 pointer들이 모여있다. 
      • Job queue: 모든 process들이 있음
      • Ready queue: Ready state의 process들이 있음. ready 뿐 아니라 다른 모든 state에 대해서도 각각 queue가 존재 
      • Device queue: Device에 I/O를 요청한 뒤, Interrupt를 기다리는 process들이 있음 

    Schedulers

    • 몇 가지 종류가 있는데, 대표적으로 Long-term scheduler (job scheduler)와 Short-term scheduler (CPU scheduler)가 있다. 
    • Long-term scheduler (Job scheduler): 새로 만든 Process를 대상으로 CPU를 줄 대상으로 볼지 말지를 결정
      • 자주 돌지 않는 scheduler로, 새로운 Process가 생길때만 작동한다
      • 작동 예시: Real-time system에서 지금 돌아가는 process는 그 deadline 안에 끝남을 무조건 보장해야하는데, 새로운 process가 생기면 그를 위해 CPU와 memory를 할당 해 줘야한다. 이 때, 기존의 process에게 줄 수 있는 CPU와 memory가 줄어든다. 따라서, 이 시점에 새로운 process를 받아들이면, 기존의 process를 deadline 안에 맞춰서 끝낼 수 있을지를 판단하고, 새로운 process를 돌릴지 말지 결정 해야한다. 이 일을 해 주는 것이 바로 Job scheduler다
      • the degree of multiprogramming (현재 돌고 있는 process의 수)를 관리한다
    • Short-term scheduler (CPU scheduler): (매우중요) 현재 Ready 상태인 process들 중에서 어떤 process에게 CPU를 줄지 결정
      • 우리가 일반적으로 하는 scheduler. 매우 빈번하게 작동한다
      • 따라서 이 scheduler로 인한 overhead를 최소화 하고 효율을 최대화 시키고자 하는 연구가 많이 진행되었다
    • (추가) Midium-term scheduler: memory에 관련된 scheduler로, memory가 부족한 경우 다른 process를 memory에서 내려서 하드 디스크에 저장
      • memory 부족이 발생할 경우만 작동한다
      • memory를 확보해서 하고자 하는 일을 수행하는 것이 목표다
      • 나중에 memory에서 내린 process(P0)를 다시 돌리고 싶으면, memory에 올라간 다른 process(P1)를 다시 내리고, P0를 수행한다. 이것을 Swap이라고 부른다
      • Swap 대상을 결정하는 것이 midium-term scheduler의 역할이다
    • Process의 종류는 I/O bound process와 CPU bound process로도 나눌 수 있다
      • I/O bound process: many short CPU burts가 특징으로 I/O 발생이 잦은 process
      • CPU bound process: I/O 발생이 적어서, 한번 CPU 잡으면 system call 발생 전까지 주욱- 일하는 process

    Context Switch

    • Process 간의 이동 과정을 의미
    • Context-Switch time is overhead = 그야말로 OVERHEAD 그 자체다
    • 하드웨어 지원을 통해 이 overhead를 줄일 수 있었다. 그러나 또 다른 문제로 Cache flushing에 의한 context switch 이후 발생하는 cache miss가 overhead를 발생시킨다.
      • Context-switch에 의한 overhead 대부분이 cache miss에 의한 것
      • P0가 P1에게 CPU를 빼앗기면서 update 된 내용은 memory에 기록하고, P0의 cache를 모두 날린다 >> cache flushing
      • 이제 P1의 data가 cache를 채우기 시작한다. Cache의 목적은 여기에서 빨리빨리 data를 가져오기 위함인데, context switch 때문에, cache가 다 비워져 있다. 따라서 P1을 위해서는 초반에 계속해서 cache miss가 발생한다. (cache에 원하는 내용이 없어서 계속 memory에 접근해야하는 상황)
      • 이로 인해 속도가 엄청나게 느려진다... 
      • 따라서 여전히 context-switch의 overhead는 상.당.하.다

    Process Creation

    • Fork System Call에 의해 process를 생성 
      • return value: child process ID
      • child process의 PID = 0 (PID = 0이면 자식 process)
      • 부모와 같은 일을 하는 자식 process를 생성한다 (Default)
      • 이후, exec system call을 통해서 자식 process가 다른 일을 할 수 있다
    • 부모 process가 자식 process를 fork한다. 타고 올라가면 그 부모를 fork한 process가 또 존재한다. 또 타고 올라가면... 이런 식으로 쭉쭉 반복하다보면 tree of processes (가계도)가 생긴다. 
    • 최초의 process (Initial process): OS가 booting 시에 만듦. 이것 외에는 모두 fork에 의해 생성
      • 모든 process는 가계도를 따라 올라가면 initial process를 만난다
    • Resource sharing: 부모와 자식은 resource (data, instruction) 를 공유할 수도 있고 공유하지 않을 수도 있다

     

    Process Termination

    • Exit System Call에 의해서 process 종료
      • return value 존재하면 그 값을 wait하고 있던 parent process에게 전달
      • Program이 잡고 있던 resource를 모두 해제함
    • Abort: process의 수행을 중단
      • case 1: 사용자가 kill
      • case 2: process의 이상동작 때문에 OS가 강제로 Kill 

    Interprocess Communication

    • Process 간에는 서로 간섭하지 않는 것이 원칙이다. 하지만 목적에 따라서 긴밀한 협력이 필요할 때도 있다. 
    • 예시 시나리오: P1과 P2는 거대한 program의 일부이다. P1은 a 함수를 돌리고, P2는 b 함수를 돌린다. P1의 결과를 P2에게 전달하여 P2가 그것을 활용하여 연산하고, P1은 P2에게 결과를 보내주는 계산이 가능하다. 즉, 서로 독립적인 process이지만, 서로 data 를 교환해야하는 경우가 발생한다. 
    • Interprocess Communication (IPC): Process 간의 Protection을 지키는 한도 내에 두 process 간의 통신을 가능하게 해 주는 방법
      • 방식 1: Share memory 
        • 두 process가 공유하는 memory를 가짐
        • P0가 memory에 쓴 값을 P1이 사용 가능
      • 방식 2: Message passing 
        • 공유된 memory 공간이 있는 것이 아니라, P0가 P1에게 메세지를 직접 보내는 방식 
        • OS가 channel을 형성하면 process끼리 직접 통신

    Synchronization

    • Message passing과 관련하여 process간의 통신에서 P0가 P1에게 "이 데이터 읽어가"라고 메세지를 보냈으나, P1이 읽지 않는 경우, P0는 어떻게 해야할까? 
      • P1이 가져갈 때까지 버텨 (신뢰성↑) = Blocking = Synchronization
      • P1이 알아서 하겠지 하고 P0 자신이 해야할 일을 해 (효율성↑, 신뢰성↓) = Non-blocking = Asynchronization

     

    댓글

Written by Geulleun