[OS] 4. 프로세스


프로세스

  • 프로그램이 실행되면 프로세스가 된다.

    Untitled

  • 프로세스는 컴퓨터 시스템의 작업 단위태스크(task)라고도 부른다.
    • 프로그램은 저장장치(e.g. 하드디스크)에 저장되어있는 정적인 상태
    • 프로세스는 실행을 위해 메모리에 올라온 동적인 상태
  • 프로그램을 더블 클릭하여 실행하면 운영체제(OS)는 1) 프로그램을 메모리의 적당한 위치로 가져온다. 그리고 2) 프로세스 제어 블록을 만든다.
  • 시분할 방식
    • CPU 가 1개인 컴퓨터에서 여러 개의 프로세스를 동시에 실행한다.
    • CPU 가 시간을 쪼개어 여러 프로세스에 적당히 배분함으로써 동시에 실행하는 것처럼 느껴진다.

프로세스의 상태 (Process Status)

  • 대부분의 프로세스는 생성, 준비, 실행, 대기, 완료 상태로 운영되며 이 다섯 가지 상태를 활성 상태(Active Status)라고 한다.
  • 활성 상태 외에 휴식 상태와 보류 상태가 있다.

    Untitled프로세스의 상태

  • 활성 상태(Active Status)
    1. 생성 상태(Create Status/New Status)
      • 프로세스가 메모리에 올라오고 운영체제로부터 프로세스 제어 블록을 할당받아 실행 준비를 완료한 상태
    2. 준비 상태(Ready Status)
      • 생성된 프로세스가 CPU 를 얻을 때까지 기다리는 상태
      • 여러 프로세스 중 다음에 실행할 프로세스를 선정하는 일은 CPU 스케줄러가 담당한다.
      • 프로세스 제어 블록준비큐(Ready Queue)에서 기다리며 CPU 스케줄러에 의해 관리된다.
      • PID(Process ID): 프로세스 구분자
    3. 실행 상태(Running Status/Execute Status)
      • 준비 상태에 있는 프로세스 중 하나가 CPU 를 얻어 실제 작업을 수행하는 상태
      • 준비 상태의 프로세스 중 실행 상태에 들어가는 프로세스는 CPU 의 개수 만큼이다.
      • 준비 상태의 프로세스 중 하나를 골라 실행 상태로 바꾸는 CPU 스케줄러의 작업을 디스패치(Dispatch)라고 한다.
      • 프로세스에 배당된 작업 시간을 타임 슬라이스 또는 타임 퀀텀이라고 부른다.
      • 프로세스에게 주어진 하나의 타임 슬라이스 동안 작업을 끝내지 못하면 다시 준비 상태로 돌아가는 상태를 타임아웃(timeout)이라고 한다.
    4. 대기 상태(Blocking Status/Wating Status)
      • 실행상 태에 있는 프로세스가 입출력을 요청하면 입출력이 완료될 때까지 기다리는 상태
      • 대기 상태의 프로세스는 입출력장치 별로(e.g.하드디스크) 마련된 큐에서 기다린다.
      • 입출력이 완료되면 인터럽트가 발생하고 대기 상태에 있는 프로세스 중 wakeup(PID) 인터럽트로 깨어날 프로세스를 찾는다.
      • wakeup(PID)로 해당 프로세스의 프로세스 제어 블록이 준비 상태로 이동한다.
      • 인터럽트 : CPU 를 사용하기 전에 거쳐야 하는 업무가 완료되었을 때, CPU 에 알림을 줌으로 CPU 가 무작정 연산이 끝날 때까지 기다리는 시간을 없애는 기술
    5. 완료 상태(Terminate Status)
      • 실행 상태의 프로세스가 주어진 시간 동안 작업을 마친 상태
      • 코어덤프(Core Dump) : 오류나 다른 프로세스에 의해 비정상 종료 혹은 강제 종료가 되면 디버깅하기 위해 강제 종료 직전의 메모리 상태를 저장장치로 옮긴다.
  • 휴식 상태(Pause Status)
    • 프로세스가 작업을 일시적으로 쉬고 있는 상태
    • 사용하던 데이터가 메모리에 그대로 있고 프로세스 제어 블록도 유지되므로 프로세스는 멈춘 지점에서 재시작할 수 있다.
    • 유닉스: 프로그램을 실행하는 도중에 ctrl+Z
  • 보류 상태(Suspend Status)
    • 프로세스가 메모리에서 잠시 쫓겨난 상태
    • 일시 정지 상태라고도 불린다.
    • 보류 상태의 프로세스는 메모리 밖으로 쫓겨나 스왑영역(Swap Area)에 보관된다.
    • 스왑영역은 메모리에서 쫓겨난 데이터가 임시로 보관되는 영역이다.
  • 프로세스의 상태 전이
    • 승인(Admitted) : 프로세스 생성이 가능하여 승인됨.
    • 스케줄러 디스패치(Scheduler Dispatch) : 준비 상태에 있는 프로세스 중 하나를 선택하여 실행시키는 것.
    • 인터럽트(Interrupt) : 예외, 입출력, 이벤트 등이 발생하여 현재 실행 중인 프로세스를 준비 상태로 바꾸고, 인터럽트가 발생한 해당 작업을 먼저 처리하는 것.
    • 입출력 또는 이벤트 대기(I/O or Event wait) : 실행 중인 프로세스가 입출력이나 이벤트를 처리해야 하는 경우, 입출력/이벤트가 모두 끝날 때까지 대기 상태로 만드는 것.
    • 입출력 또는 이벤트 완료(I/O or Event Completion) : 입출력/이벤트가 끝난 프로세스를 준비 상태로 전환하여 스케줄러에 의해 선택될 수 있도록 만드는 것.

프로세스 제어 블록 (PCB, Process Control Block)

  • 프로세스 제어 블록은 프로세스를 실행하는데 필요한 중요한 정보를 보관하는 자료구조이다.
  • TCB(Task Control Block)라고도 한다.
  • 하나의 프로세스를 실행하려면 프로세스 구분자, 메모리 관련 정보, 프로그램 카운터와 각종 레지스터 같은 중간값을 관리해야하며, 이러한 정보를 보관하는 데이터 구조가 프로세스 제어 블록이다.
    • 프로세스 구분자
      • 메모리에는 여러 개의 프로세스가 존재하므로 각 프로세스를 구분하는 구분자(Identification, ID)가 필요하다.
    • 메모리 관련 정보
      • CPU 는 실행하려는 프로세스가 메모리의 어디에 저장되어있는지 알아야한다. 프로세스의 메모리 위치 정보가 담겨있다.
    • 각종 중간값
      • 프로세스가 사용했던 중간값이다.
      • 예를 들어, 프로세스 A가 103번 행까지 작업한 후 다른 프로세스에게 CPU 를 넘겨주었다. 시간이 흘러 다시 프로세스 A 의 차례가 되면 104번 행부터 작업을 시작해야한다.
      • 이를 위해 프로세스 제어 블록에는 다음에 작업해야할 코드의 위치가 담긴 레지스터인 프로그램 카운터가 저장된다.
  • 따라서 PCB 는 운영체제가 프로세스를 제어하기 위한 정보를 저장해놓는다.
  • 또한 PCB 는 Context Switching(문맥 교환)을 위해 필요하다.
  • 어떤 프로그램이 프로세스가 되었다는 것은 운영체제로부터 프로세스 제어 블록을 받았다는 의미이다.
    • 모든 프로세스는 고유의 프로세스 제어 블록을 가진다.
    • 프로세스 제어 블록은 프로세스 생성 시 만들어져서 프로세스가 실행을 완료하면 폐기된다.
  • 프로그램 실행 $\rightarrow$ 프로세스 생성 $\rightarrow$ 프로세스 주소 공간에 코드, 데이터, 스택, 힙 생성 $\rightarrow$ 이 프로세스의 메타데이터들이 PCB 에 저장
  • PCB 구성
    • 포인터
    • 프로세스 상태: 생성, 준비, 실행, 대기, 보류등
    • 프로세스 구분자: PID
    • 프로그램 카운터
    • 프로세스 우선순위: CPU 스케줄러가 준비 상태의 프로세스를 실행 상태로 옮길 때, 프로세스 우선순위를 기준으로 삼는다.
    • 각종 레지스터 정보
    • 메모리 관리 정보
    • 할당된 자원 정보
    • 계정 정보
    • 부모 프로세스 구분자와 자식 프로세스 구분자

프로세스의 구조

  • 프로세스는 생성과 동시에 코드 영역, 데이터 영역, 스택 영역, 힙 영역 4가지 메모리 영역으로 구성된다.

    Untitled

  • 서로 다른 프로세스 간에 메모리 공간 접근은 허용되지 않는다. 즉 공유하지 않는다.

  1. 코드 영역 (Code Area, Text Area)
    • 프로그램의 본문이 기술된 곳
    • 프로그래머가 작성한 프로그램은 코드 영역에 탑재된다.
    • 읽기 전용
  2. 데이터 영역 (Data Area)
    • 코드가 실행되면서 사용하는 변수나 파일등의 각종 데이터를 모아놓은 곳
    • 읽기와 쓰기
  3. 스택 영역 (Stack Area)
    • 운영체제가 프로세스를 실행하기 위해 부수적(임시)으로 필요한 데이터를 모아놓은 곳
  4. 힙 영역 (Heap Area)
    • 동적으로 할당되는 데이터들을 위해 존재하는 공간이다. - 예시
      1. 워드프로그램을 실행하면 이 프로그램은 코드 영역에 탑재된다.
      2. 워드프로세스로 편집중인 문서는 데이터 영역에 탑재된다.
      3. 운영체제가 워드프로세스를 작동하기 위해 사용하는 각종 부가데이터는 스택 영역에서 관리한다.

프로세스의 생성과 복사

  • 프로세스에서 생성과 종료 과정을 생성과 복사 & 종료 과정이라고 이야기한다.
  • 복사를 같이 이야기하는 이유는 우리가 흔히 더블클릭을 통해 사용하는 API 들은 다 부모 프로세스를 복사해서 실행시킨 자식 프로세스이기 때문이다.
  • 프로세스의 생성과 복사 그리고 종료의 과정은 Window 와 Unix 에서 차이가 있다. Unix 만 보자.
  • fork()
    • 커널에서 제공하는 실행 중인 프로세스로부터 새로운 프로세스를 복사하는 함수
    • fork() 시스템 호출을 하면 실행중인 프로세스와 똑같은 프로세스가 만들어진다.
    • 즉 자식 프로세스를 생성할 때 부모 프로세스가 대기 상태에 들어가는 것이 아닌, 같이 실행되는 구조를 가지고 있고 자식과 부모의 가상 메모리가 동시에 존재해 추가적인 작업들이 필요하다.
    • 예시
      • 워드프로세스 문서로 작업을 하다가 새로운 워드프로세스 프로그램을 하나 더 실행하면 운영체제는 새로운 워드프로세스 프로그램을 실행하지 않고 fork()를 사용하여 기존의 워드프로세스를 복사한다. 이렇게 복사하면 처음 워드프로세스 프로그램을 실행하는 속도보다 훨씬 빠르다.
      • 크롬에서 ctrl+N 을 누르면 크롬이 하나 더 실행된다. 이는 새로운 크롬을 실행한 것이 아니라 현재의 크롬 프로세서를 복사한 것이다. 프로세스를 복사할 때 기존의 프로세스는 부모 프로세스가 되고 새로 생긴 프로세스는 자식 프로세스가 되며 두 프로세스는 부모-자식 관계로 연결된다.
    • 장점
      1. 프로세스의 생성 속도가 빠르다.
        • 하드디스크로부터 프로그램을 새로 가져오지 않고 기존 메모리에서 복사하기 때문에 자식 프로세스의 생성속도가 빠르다.
      2. 추가 작업 없이 자원을 상속할 수 있다.
        • 부모 프로세스가 사용하던 모든 자원을 자식 프로세스에게 생속할 수 있다.
      3. 시스템 관리를 효율적으로 할 수 있다.
        • 부모 프로세스와 자식 프로세스가 자식 프로세스 구분자와 부모 프로세스 구분자로 연결되어있기 때문에, 자식 프로세스를 종료하면 자식이 사용하던 자원을 부모 프로세스가 정리할 수 있다.
  • exec()
    • 기존의 프로세스를 새로운 프로세스로 전환하는 함수
    • 기존의 프로세스 구조를 그대로 둔 채, 내용만 바꾸어 새로 실행한다.
      • 프로세스 구분자(PID, PPID, CPID)만 남겨두고 프로세스의 나머지 내용을 새 것으로 바꾼다.
      • 데이터 영역이 새로운 데이터로 채워지고 스택 영역이 리셋된다.
    • 자식 프로세스를 생성할 때 부모 프로세스가 대기 상태에 들어가고 자식 프로세스는 부모 프로세스의 가상메모리 공간을 가져다 쓴다.
    • 따라서 새로운 가상메모리 공간 생성이나 기존 공간 삭제 등 다양한 후처리 작업들을 줄여 효율성을 가져올 수 있게 해준다.
    • 새로운 프로세스를 만들려면 프로세스 제어 블록을 만들고 메모리의 자리를 확보해야한다. 또한 프로세스를 종료한 후 사용한 메모리를 청소(Garbage Collection)하기 위해 상위 프로세스에 부모-자식 관계를 만들어야한다.
    • 이 때 exec() 를 사용하면 이미 만들어진 프로세스 제어 블록, 메모리 영역, 부모-자식 관계를 그대로 사용할 수 있다.
  • 프로세스 생성과 복사 & 종료 과정
    1. fork()를 통해 새로운 프로세스를 만든다.
      • 새로운 프로세스는 자식 프로세스라 부르고, 오리지널 프로세스는 부모 프로세스가 된다.
      • 새로운 자식 프로세스가 해당 부모 프로세스의 주소 공간을 복사하고 있다.
    2. 자식 프로세스는 실행됨과 동시에 부모 프로세스는 함께 실행되고 있다.(윈도우와 차이점)
      • exec()를 통해 부모 프로세스를 대기 상태로 만들어 윈도우와 비슷하게 작동하게 할 수도 있다.
    3. 자식 프로세스가 exit() 시그널을 보내면, 자식 프로세스는 종료된다. 이 때 부모 프로세스가 대기 상태에 있는 경우 부모 프로세스를 다시 실행시킨다.

고아 프로세스(Orphan Process)

  • 고아 프로세스는 프로세스가 종료된 후에도 비정상적으로 남아있는 프로세스다. 고아 프로세스는 부모 프로세스가 자식보다 먼저 죽는 경우에 발생한다.
  • 비슷하게 좀비 프로세스가 있다. 좀비 프로세스는 자식 프로세스가 종료했음에도 부모가 뒤처리를 하지 않을 때 발생한다.
  • 고아/좀비 프로세스가 많아지면 자원이 낭비된다.
  • 컴퓨터를 오래 켜두면 느려지는 현상?
    • 부팅할 때는 없었던 각종 프로세스가 메모리에 상주하는데다 좀비 프로세스가 메모리를 차지하기 때문이다.
    • 다시 부팅하면 속도가 빨라지는데, 이는 메모리에서 찌꺼기가 사라졌기 때문이다.

Context Switching (문맥 교환)

  • CPU 를 차지하던 프로세스가 나가고 새로운 프로세스를 받아들이는 작업을 말한다.
  • 두 프로세스의 프로세스 제어 블록을 교환하는 작업이다.
  • 즉 CPU 가 현재 실행하고 있는 Task(Process, Thread)의 상태를 저장하고, 다음 진행할 Task 의 상태 및 Register 값들에 대한 정보(Context)를 읽어 새로운 Task 의 Context 정보로 교체하는 과정이다.
  • 쉽게 설명해서 CPU 가 이전의 프로세스 상태를 PCB 에 보관하고, 또 다른 프로세스의 정보를 PCB 에서 읽어서 레지스터에 적재하는 과정을 말한다.

    Untitled

  • Context Switching 은 Ready $\rightarrow$ Running , Running $\rightarrow$ Ready , Running $\rightarrow$ Block 처럼 상태 변경시에 발생한다.
    • 실행 상태에서 나가는 프로세스 제어 블록에는 지금까지의 작업을 저장한다.
    • 실행 상태로 들어오는 프로세스 제어 블록의 내용으로 Register에 적재하고 CPU가 다시 세팅된다.
  • 발생 조건
    • 프로세스의 주어진 시간을 다 사용했을 경우
    • 인터럽트가 걸렸을 때
    • 프로세스가 자신에게 주어진 메모리 공간을 넘어갈 때
  • 시간 할당량
    • 프로세스들의 시간 할당량은 시스템 성능의 중요한 역할을 한다.
    • 시간 할당량이 적을수록 사용자 입장에서는 여러 개의 프로세스가 거의 동시에 수행되는 느낌을 갖지만 인터럽트의 수와 문맥 교환의 수가 늘어난다.
    • 프로세스의 실행을 위한 부가적인 활동을 오버헤드(간접 부담 비용)라고 하는데, 이 또한 문맥 교환 수와 같이 늘어나게 된다.
    • 시간 할당량이 적어지면 : 문맥 교환 수, 인터럽트 횟수, 오버헤드가 증가하지만 여러 개의 프로세스가 동시에 수행되는 느낌을 갖는다.
    • 시간 할당량이 커지면 : 문맥 교환 수, 인터럽트 횟수, 오버헤드가 감소하지만 여러 개의 프로세스가 동시에 수행되는 느낌을 갖지 못한다.

정적 할당 영역

  • 코드 영역데이터 영역프로세스가 실행되기 전에 위치와 크기가 결정되고 실행되는 동안 변하지 않으므로 정적 할당 영역이다.
    • 코드 영역: 프로그램의 본체가 있는 곳
    • 데이터 영역: 프로그램이 사용하려고 정의한 변수와 데이터가 있는 곳

동적 할당 영역

  • 스택 영역힙 영역프로세스가 실행되는 동안 만들어지는 영역으로 그 크기가 늘어났다 줄어드는 동적 할당 영역이다.
    • 스택(Stack)
      • 호출한 함수가 종료되면 함수를 호출하기 전 코드로 되돌아와야 하는데 되돌아올 메모리 주소를 스택에 저장한다.
      • 변수 사용 범위에 영향을 미치는 영역(scope)을 구현할 때 사용한다.
      • 함수에서 사용하는 지역변수는 함수가 호출될 때만 사용되다가 함수가 종료되면 사용한 공간을 반환해야하는데, 지역변수를 저장할 때 스택이 사용된다.
      • 스택은 프로세스를 작동하기 위해 커널이 유지하는 자료구조이다.
      • 스택은 스레드가 작동하는 동안 추가되거나 삭제되는 영역이다.
      • LIFO (Last in first out)
    • 힙(Heap)
      • 동적으로 할당되는 변수 영역이다.
      • e.g. malloc()
맨 위로 이동 ↑

댓글 남기기