학교/운영체제

[운영체제] 3. 프로세스 관리

daykim 2023. 1. 16. 17:15
도서 기반 내용 정리
 

운영체제 | Abraham Silberschatz - 교보문고

운영체제 | ▶ 이 책은 운영체제론을 다룬 이론서입니다. 운영체제론의 기초적이고 전반적인 내용을 학습할 수 있습니다.

product.kyobobook.co.kr

 

목차

  • 프로세스 개념
  • 프로세스 스케줄링
  • 프로세스에 대한 연산
  • 프로세스 간 통신
  • 공유 메모리 시스템에서의 프로세스 간 통신
  • 메시지 전달 시스템에서의 프로세스 간 통신
  • IPC 시스템 사례
  • 클라이언트 서버 환경에서 통신

 

프로세스 개념


  • 프로그램 : 명령어 리스트를 내용으로 가진 디스크에 저장된 파일(실행파일)과 같은 수동적 존재
  • 프로세스 : 다음에 실행할 명령어를 지정하는 프로그램 카운터와 관련 자원의 집합을 가진 능동적인 존재
  • 실행 파일이 메모리에 적재될 때 프로그램은 프로세스가 된다.

프로세스 메모리 배치

- 크기 고정
  • 텍스트 섹션 : 실행 코드
  • 데이터 섹션 : 전역 변수
- 크기 동적
  • 힙 섹션 : 프로그램 실행 중 동적으로 할당되는 메모리
  • 스택 섹션 : 함수를 호출할 때 임시 데이터 저장장소 (함수 매개변수, 복귀 주소, 직역변수)
  • 함수가 호출될 때 활성화 레코드가 스택에 푸시된다.
  • 활성화 레코드 : 함수 매개변수, 지역 변수 및 복귀주소 포함
  • 스택 및 힙 섹션이 서로의 방향으로 커져도 운영체제는 서로 겹치지 않게 해야한다.

프로세스 상태 (Process State)

프로세스는 실행되면서 그 상태가 변한다.

  • new : 프로세스 생성 중
  • running : 명령어들이 실행되는 중
  • waiting : 프로세스가 어떤 이벤트가 일어나길 기다리는 중
  • ready : 프로세스가 처리기(프로세서)에 할당되길 기다리는 중
  • terminated : 프로세스 실행이 종료됐다.

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

프로세스에 관한 정보가 수록된 곳

  • 프로세스 상태 (Process State)
  • 프로그램 카운터 (Process counter) : 프로세스가 다음에 실행할 명령어의 주소
  • CPU registers : 프로세스가 인터럽트 발생 후 다시 스케줄 될 때, 계속 올바르게 실행되도록 저장되는 값
  • Memory 관리 정보
  • 회계(Accounting) 정보 : CPU 사용 시간, 시간 제한, 프로세스 번호 등
  • 입출력 상태 정보(I/O status information) : 프로세스에 할당된 입출력 장치들과 열린 파일의 목록 등

 

프로세스 스케줄링 (Process Scheduling)


  • 멀티 프로그래밍 목적 : CPU 이용을 최대화 하기 위해 항상 어떤 프로세스가 실 되도록 하는 것이다.
  • 시분할(Time sharing) 목적 : 각 프로그램이 실행되는 동안 사용자가 상호 작용할 수 있도록, 프로세스들 사이에서 CPU 코어를 빈번히 교체하는 것이다.

이 목적 달성을 위해 프로세스 스케줄러는 코어에서 프로그램 실행 가능한 여러 프로세스 중 하나를 선택한다.

스케줄링 큐 (Scheduling Queue)

  • 프로세스가 시스템에 들어가면 ready queue에 들어가 준비상태가 되어 CPU 코어에서 실행되길 기다린다.
    이 큐는 연결리스트로 저장된다.
  • I/O 완료와 같은 특정 이벤트가 발생하기를 기다리는 프로세스는 wait queue에 들어간다.

Scheduling Queue의 흐름

queueing diagram

  • 새 프로세스는 처음에 ready queue에 놓인다.
  • 프로세스는 실행을 위해 선택되거나 dispatch 되기를 기다린다.
  • 프로세스에 CPU 코어가 할당돼 실행상태가 되면, 여러 이벤트 중 하나가 발생한다.
  • 프로세스 종료될 때 까지 이 주기를 반복한다.
  • 종료 시점에 모든 큐에서 제거되고, PCB 및 자원이 반환된다.

 

CPU Scheduler

  • ready queue에 있는 프로세스 중에서 선택된 하나의 프로세스에 CPU 코어를 할당하는 역할

 

스와핑 (Swapping)

  • 때로 메모리에서 프로세스를 제거해 멀티 프로그래밍 정도를 감소시키는 것이 유리할 수 있다는 스케줄링 기법
  • 스왑 아웃 : 프로세스를 메모리에서 디스크로 옮기는 것
  • 스왑 인 : 디스크에서 메모리로 상태를 복원하는 것
  • 일반적으로 메모리가 초과 사용돼 가용 공간을 확보해야 할 때만 필요하다.

 

Context Switch (문맥 교환)

인터럽트가 발생했을 때, CPU 코어를 다른 프로세스로 교환(Switch)하기 위해 이전의 프로세스 상태를 보관하고 새로운 프로세스의 보관된 상태를 복구하는 작업이다.

  • 커널은 이전 프로세스의 작업이 끝나지 않았다면 Context를 PCB에 저장하고, 새로운 프로세스 정보로 덮어씌운다.
  • Context Switch가 발생되는 동안 시스템에선 다른 일을 못하기 때문에 이 시간은 순수한 오버헤드다.
    따라서 너무 자주하는 경우 성능을 저하시킨다.

context switch 보여주는 diagram

 

프로세스에 대한 연산 (Operation on Processes)


프로세스 생성 (Process Creation)

실행되는 동안 프로세스는 여러개의 새로운 프로세스 생성 가능하다.

부모 프로세스가 자식 프로세스를 생성한다.
이는 트리구조로 되어있다.

pid (process identifie)

프로세스 식별자로 보통 정수이다.

  • fork() 함수 호출 시 부모 프로세스는 자신과 똑같은 자식 프로세스 생성
    -> 자식은 부모의 복사본으로, 똑같은 프로그램과 데이터를 가진다.
  • 자식 프로세스는 exec() 함수를 통해 내용을 바꾼다.
  • fork() 함수는 부모에겐 자식 프로세스의 pid, 자식에겐 0을 반환한다.
  • 자식 프로세스는 자원을 운영체제에게 직접 얻거나,
    부모 프로세스가 가진 자원의 부분 집한만을 사용하도록 제한될 수 있다.

프로세스가 새로운 프로세스를 생성할 때, 두 프로세스를 실행하는 두가지 방법이 있다.

  1. 부모는 자식과 병행하게 실행을 계속한다.
  2. 부모는 일부 또는 모든 자식이 실행을 종료할 때까지 기다린다.

fork() 사용한 프로세스 생성

  • fork() : 호출한 프로세스를 복사한다. 호출한 프로세스는 부모, 복사된 프로세스는 자식이라 한다.
  • exec() : 호출한 프로세스의 메모리를 새로운 프로세스로 덮어쓴다.
  • 참고

 

프로세스 종료 (Process Termination)

프로세스가 exit() 시스템 콜을 사용해 운영체제에 자신의 삭제를 요청하면 종료한다.
프로세스는 자신을 기다리고 있는 부모 프로세스에 상태값을 반환할 수 있다.
프로세스의 모든 자원이 할당 해제되고, 운영체제로 반납된다.

프로세스는 적당한 시스템콜을 통해 다른 프로세스의 종료를 유발할 수 있다.
통상적으론 종료될 프로세스의 부모만 호출 가능하다.

프로세스가 정상적이든 비정상적이든 종료되면, 그로부터 비롯된자식 프로세스도 종료된다.
-> 연쇄식 종료(cascading termination)

부모 프로세스가 자식 프로세스보다 먼저 종료되면,
자식 프로세스는 그 상위 프로세스를 부모 프로세스로 바라본다.

  • 부모 프로세스는 자식 프로세스의 종료를 인지 한 후 wait()를 호출해야 한다.
    종료된 자식 프로세스에 대한 정보가 삭제되지 않고, 남아있게 되기 때문이다.

 

좀비(Zombie) 프로세스

자식 프로세스가 종료됐는데, 부모가 wait()를 호출하지 않은 프로세스

고아(Orphan) 프로세스

부모 프로세스가 wait()를 호출하지 않고, 종료된 프로세스

 

프로세스 간 통신 (Interprocesss Communication(IPC)


  • 독립적 프로세스 : 시스템 상에서 실행중인 다른 프로세스들과 데이터를 공유하지 않는 프로세스
  • 협력적 프로세스 : 프로세스가 다른 시스템에서 실행중인 다른 프로세스들에게 영향을 주거나 받는 프로세스

 

협력적 환경 제공하는 이유

  • 정보 공유
  • 계산 가속화 : 병렬 실행
  • 모듈성

 

IPC 기법 모델

  • 공유 메모리 (Shared Memory)
  • 메시지 패싱 (Message Passing)

통신 모델 (a) 공유 메모리, (b) 메시지 패싱

 

공유 메모리 (Shared Memory) 시스템에서 IPC

통신하는 프로세스들이 공유 메모리 영역을 구축해야 한다.
프로세스들은 그 영역에 데이터를 읽고, 씀으로 정보를 교환한다.

  • 프로세스들은 동일한 위치에 쓰지 않도록 해야한다. -> 충돌 조심
  • 메시지 전달보다 빠르다. -> 공유 메모리 영역을 구축할 때만 시스템콜이 필요하기 때문이다.

생산자 - 소비자 문제

  • 생산자 프로세스 : 정보 생성
  • 소비자 프로세스 : 정보 소비

두 프로세스가 동시에 동작할 때 발생하는 문제를 말한다.

해결책은 공유 메모리를 사용하는 것이다.
생산자가 한 항목을 생산하고, 그동안 소비자는 다른 항목을 소비할 수 있다.

  • 무한 버퍼 : 소비자는 새로운 항목을 기다려야 할 수 도 있지만, 생산자는 항상 새로운 항목 생산 가능
  • 유한 버퍼 : 버퍼가 비어있으면 소비자는 반드시 대기, 버퍼가 모두 채워져 있으면 생산자는 반드시 대기

 

메시지 패싱 (Message Passing) 시스템에서 IPC

협력 프로세스들 사이에서 교환되는 메시지를 통해 이루어진다.

  • 충돌을 피할 필요가 없어, 적은 양의 데이터를 교환하는데 유용하다.
  • 공유 메모리보다 구현이 쉽다.
  • 시스템 콜을 사용해 구현되므로 -> 커널을 통해 정보를 전달하고 수신한다.
    시간 소비가 된다. -> 속도가 느리다.

 

메시지 패싱 통신 연결

  • 직접 통신 (Direct Communication)
    통신을 원하는 각 프로세스는 통신의 수신자 또는 송신자의 이름을 명시한다.
    • send(P, message) : P한테 전송
    • receive(Q, message) : Q로부터 수신
    • 이 기법은 프로세스를 지정하는 방식 때문에 모듈성을 제한한다.
      프로세스가 이름을 바꾸면, 다른 프로세스 지정 부분을 검사할 필요가 있기 때문이다.
  • 간접 통신 (Indirect Communication)
    메시지들은 메일박스(mail box) 또는 포트(port)로 송신되고, 그것으로부터 수신된다.
    • send(A, message) : 메시지를 메일박스 A로 송신
    • receive(A, message) : 메시지를 메일박스 A로부터 수신
    • 만약 3개 이상의 프로세스가 한 메일박스를 공유한다면, 한 프로세스가 송신한 것을 어느 프로세스가 수신할까?
      -> 해결 방법
      1. 하나의 메일 박스는 최대 2개의 프로세스와 연관 되도록 한다.
      2. 한 순간 최대 하나의 프로세스가 receive() 연산을 실행하도록 한다.
      3. 어느 프로세스가 메시지를 수신할지 시스템이 임의로 선택하게 한다.

 

메시지 패싱 동기화(Synchronization)

  • Blocking send : 송신자가 보낸 메시지를 수신자가 수신할 때까지 송신자는 block된다.
  • Blocking receive : 메시지를 수신할 때까지 수신자는 block 된다.
  • Non-blocking send : 송신자가 메시지를 보내고 작업을 재시작한다.
  • Non-blocking receice : 수신자가 유효한 메시지나 Null을 받는다.

 

버퍼링

직접, 간접 통신 모두 교환되는 메시지는 임시 큐에 들어가 있다.

  • 무용량 (zero capacity)
    : 큐의 최대 길이가 0
     이 경우, 송신자는 수신자가 메시지를 수신할 때까지 기다려야 한다.
  • 유한 용량 (bounded capacity)
    : 큐는 유한 길이 N을 가진다.
     최대 n개의 메시지가 그 안에 들어갈 수 있다.
    큐가 만원이라면, 송신자는 큐 안에 공간이 이용 가능할 때까지 blocking되어야 한다.
    만원이 아니라면, 송신자는 큐에 메시지를 놓고 대기하지 않고 실행을 계속한다.
  • 무한 용량 (unbounded capacty)
    : 큐는 무한 길이를 가진다.
    따라서 메시지들은 얼마든지 큐 안에 대기할 수 있고, 송신자는 blocking되지 않는다.

 

IPC 시스템 사례


Window

두 프로세스간에 연결을 구축하고 유지하기 위해 포트 객체 사용

  • 연결 포트 (Connection Port)
  • 통신 포트 (Communication Port)

파이프 (Pipes)

두 프로세스가 통신할 수 있게 하는 전달자로 동작한다.

  • 부모 프로세스와 자식 프로세스가 통신할 때 사용
  • 단방향 통신만 가능하다.
    양방향 정보를 주고 받으려면, 파이프 두 개 사용
  • 지명 파이프(named pipe)를 사용하면 부모, 자식 관계가 아니어도 사용 가능하다.

 

클라이언트 서버 환경에서 통신 (Communication in Client - Server Systems)


소켓 (Socket)

소켓은 통신의 극점(endpoint)을 뜻한다.
다른 기계에 있는 두 프로세스가 네트워크 상 통신을 하려면 양 프로세스 각각 소켓이 필요하다.

  • 소켓은 IP 주소와 포트 번호 두가지를 접합해 구별한다.
  • 서버는 지정된 포트에 클라이언트 요청 메시지가 도착하길 기다린다.
    요청이 수신되면 서버는 클라이언트 소켓으로부터 연결 요청을 수락함으로써 연결된다.

 

소켓을 이용한 통신은 너무 낮은 수준이다.
더 높은 수준은 원격 프로시저 호출(RPC)다.

 

원격 프로시저 호출 (Remote Procedure Calls, RPC)

다른 컴퓨터에 있는 프로세스에서 함수를 호출할 수 있는 프로세스간 통신 기술이다.

  • RPC를 이용시, 프로그래머는 함수가 실행 프로그램 로컬에 있든, 원격 위치에 있든 동일한 코드를 이용할 수 있다.
  • RPC를 이용하면, 언어에 구애받지 않고, 원격 프로시저를 호출해 비즈니스 로직에 집중할 수 있다.
  • 네트워크에 연결된 두 시스템 사이의 통신에 사용하기 위해 프로시저 호출 기법을 추상화하는 방법으로 설계됐다.
  • 클라이언트 쪽에서 stub을 제공해 통신을 하는데 필요한 자세한 사항들을 숨겨준다.