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

프로세스 개요

1) 프로세스

  • 프로그램: 하드디스크 등의 저장 매체에 저장되며 실행 파일의 형태를 가짐

#1 프로세스

  • 프로그램이 메모리에 적재되어 실행 중인 상태
  • 필요한 모든 자원을 할당 ( 코드공간, 데이터공간, 힙공간, 스택공간 )

#2 프로세스의 특징

  • 운영체제는 프로그램을 메모리 적재하고 프로세스로 다룸
  • 운영체제는 프로세스에 필요한 메모리를 할당
  • 프로세스는 서로 독립적인 메모리 공간을 가짐
  • 커널은 각 프로세스의 메모리 위치와 크기 정보를 관리
  • 커널은 프로세스마다 고유한 번호 (PID) 할당
  • 프로세스의 정보는 커널이 관리
  • 프로세스는 실행-대기-잠자기-대기-실행-종료 등의 생명 주기
  • 프로세스 생성, 대기, 종료 등의 관리는 모두 커널에 의해 수행

#3 프로세스 관리

  • 프로세서의 생성에서 종료까지 관리는 모두 커널에 의해 이루어짐
  • 커널 영역에 프로세스 테이블을 생성, 프로세스의 목록 관리
  • 프로세스 생성, 실행, 일시 중단 및 재개, 정보 관리, 프로세스 통신, 프로세스 동기화, 프로세스 컨텍스트 스위칭

#4 프로그램의 다중 인스턴스

  • 한 프로그램을 여러 번 실행시켜 다중 인스턴스 생성
  • 운영체제는 프로그램을 실행할 때마다 독립된 프로세스 생성
  • 다중 인스턴스 프로세스들을 별개로 취급

2) 프로세스의 주소 공간

#1 CPU 주소 공간

  • CPU 주소선을 통해 액세스 가능한 전체 메모리 공간
  • 32비트 → 최대 4GB

#2 프로세스 메모리 영역 구성

  1. 코드 영역 : 실행될 프로그램 코드가 적재 (사용자 및 라이브러리의 함수)
  2. 데이터 영역 : 전역 변수, 정적 데이터 공간 (사용자가 선언한 전역 변수 & 라이브러리 전역 변수)
  3. 힙 영역 : 프로세스가 실행 도중에 동적으로 사용할 수 있도록 할당된 공간
  4. 스택 영역 : 함수가 실행될 때 사용될 데이터를 위해 할당된 공간

#3 프로세스 주소 공간

  • 프로세스가 실행 중에 접근할 수 있도록 허용된 주소의 최대 범위
  • 프로세스 주소 공간의 크기는 cpu가 액세스 가능한 전체 크기로 프로세스의 현재 크기와는 다름
  • 프로세스 주소 공간은 사용자 공간과 커널 공간으로 나누어짐

#4 커널 공간의 의미

  • 프로세스가 사용자 코드에서 시스템 호출을 통해 커널 코드 실행 시 커널 공간 사용
  • 사용자 공간과 커널 공간을 통해 프로세스마다 각각 사용자 공간이 있으며 하나의 커널 주소 공간을 공유하여 사용

#5 프로세스 주소 공간의 특징

  • 프로세스의 주소 공간은 가상 공간
  • 연속적인 메모리 공간에 형성된 것처럼 보이나 실제로는 물리 메모리에 각각 흩어져 저장

커널의 프로세스 관리

1) 프로세스 테이블과 프로세스 제어 블록

#1 프로세스 테이블과 제어 블록

  • 프로세스 테이블(Process Table) : 시스템이 모든 프로세스를 관리하기 위한 표 시스템에 하나만 존재
  • 프로세스 제어 블록(Process Control Block) : 프로세스에 관한 정보를 저장하는 구조체 프로세스 생성될 때 만들어지며 종료시 삭제, 프로세스당 하나씩 존재
  • 프로세스 테이블과 제어 블록의 경우 커널 영역, 커널 코드만 액세스 가능

#2 프로세스 제어 블록에 저장되는 정보

  1. 프로세스 번호(PID) : 프로세스 구분하는 유일한 번호
  2. 부모 프로세스 번호(PPID) : 부모 프로세스의 PID
  3. 프로세스 상태 정보
  4. CPU 컨덱스트 정보
  5. 스케줄링 정보
  6. 프로세스 종료 코드
  7. 열어놓은 파일 디스크립터들이 저장되는 배열
  8. 메모리 관리 정보
  9. 프로세스 사이의 통신 정보
  10. 회계 정보
  11. 프로세스 소유자 이름

#3 프로세스 생명 주기와 상태 변이

  • 프로세스는 탄생에서 종료까지 여러 상태로 바뀌면서 실행
  • 프로세스 상태
  1. 생성 상태 : 프로세스가 생성된 상태, 메모리 할당 및 필요 자원 적재
  2. 준비 상태 : 스케줄링을 기다리는 상태, 준비 큐에서 대기
  3. 실행 상태 : cpu에 의해 실행되고 있는 상태
  4. 블록/대기 상태 : 프로세스가 자원을 요청하거나 입출력을 요청하고 완료를 기다리는 상태
  5. 종료-좀비 상태 : 프로세스가 종료된 상태 혹은 부모 프로세스가 읽어가지 않아 완전히 종료되지 않은 상태
  6. 종료-아웃 상태 : 프로세스가 종료하면서 남긴 종료 코드를 읽어가서 완전히 종료된 상태, 시스템에서 PCB와 프로세스 테이블에서 항목이 완전히 제거

#4 프로세스 스케줄링과 컨텍스트 스위칭

  • 프로세스 스케줄링 : 준비 상태의 프로세스 중 실행시킬 프로세스 선택
  • 현재는 스레드를 대상으로 스케줄링
  • 현재 프로세스는 스레드들에게 공유 자원을 제공하는 컨테이너 역할

프로세스 계층 구조

#1 부모- 자식 프로세스

  • 최초의 프로세스(#0 프로세스)를 제외한 모든 프로세스는 부모 프로세스를 가짐
  • 여러 개의 자식 프로세스를 가질 수 있음
  • 자식 프로세스
    • 모든 프로세스는 부모 프로세스에 의해 생성
    • 프로세스는 시스템 호출을 통해 생성

#2 idle 프로세스와 init 프로세스 (#0과 #1 프로세스)

  • #0 프로세스
    • 최고의 조상 프로세스
    • Unix - swapper
    • 리눅스 - idle : 실행 중인 프로세스가 1개도 없는 상태에 빠지지 않기 위한 루프 프로세스
    • Windows - idle : 아무일도 하지 않고 루프를 도는 단순 프로세스

#3 프로세스를 다루는 시스템 호출

  • fork() : 자식 프로세스 생성
  • exit() : 프로세스의 종료를 커널에 알림
  • wait() : 부모가 자식 프로세스의 종료를 기다리고 확인

#4 좀비 프로세스

  • 부모 프로세스는 시스템 호출을 통해 자식 프로세스의 종료 코드를 읽어야 함
  • 좀비 프로세스는 자식 프로세스가 종료되었지만 부모 프로세스가 종료 코드를 읽지 않은 상태의 프로세스
  • SIGCHLD 신호를 보내 프로세스를 제거하거나 부모 프로세스를 강제로 종료하여 종료 코드를 읽도록 만들기

#5 고아 프로세스

  • 부모가 먼저 종료한 프로세스
  • 커널은 자식 프로세스를 init 프로세스로 입양하여 처리

#6 여러 종류의 프로세스

  • 백그라운드 프로세스 : 터머널에서 실행되나 사용자와의 대화가 없이 실행되는 프로세스
  • 포그라운드 프로세스 : 실행되는 동안 사용자의 입력을 독점하는 프로세스
  • cpu 집중 프로세스
    • 대부분의 시가을 계산 중심의 일을 처리하는 프로세스
    • cpu 성능이 좌우
  • I/O 집중 프로세스
    • 입출력 작업을 하는 데 대부분의 시간을 보내는 프로세스
    • 네트워크 전송, 파일 입출력에 집중
    • 입출력 장치나 입출력 시스템의 속도가 성능 좌우

프로세스 제어

#1 프로세스 생성

  • 시스템 부팅 / 사용자와 대화를 위한 프로세스 / 사용자의 명령을 통한 프로세스 생성 / 배치 작업 실행 / 응용프로그램의 시스템 호출 → 총 5가지의 프로세스 생성 경우
  • 시스템 호출을 통해서만 프로세스 생성

#2 프로세스 생성 과정

  • 새로운 PID 번호 생성
  • → PCB 구조체 생성
  • → 프로세스 테이블 새 항목 할당
  • → PCB를 프로세스 테이블에 연결
  • → 프로세스를 위한 메모리 공간 할당
  • → PCB에 프로세스 정보 기록
  • → 프로세스 상태를 ready로 변경 후 준비 큐에 삽입

#3 프로세스 오버레이 exec()

  • 현재 실행중인 프로세스의 주소 공간에 새로운 응용 프로그램을 적재하여 실행
  • pid 변경 없음

#4 프로세스 종료와 종료 대기

  • 프로세스 종료는 exit() 시스템 호출
  • 부모 프로세스에 전달할 종료 코드를 반환함
  • exit() 종료 과정
    • 프로세스의 모든 자원 반환
    • PCB 상태를 Terminated로 변경 후 PCB에 종료 코드 저장
    • 자식 프로세스를 init 프로세스에 입양
    • 부모 프로세스에게 SIGCHLD 신호 전송

#5 종료 코드의 의미와 범위

  • 종료 코드는 프로세스가 종료한 상태나 이유를 부모에게 전달하기 위한 코드
  • 0~255의 1바이트 숫자
  • 따라서 255이상의 값을 사용할 경우 개발자의 의도와 다른 종료를 의미할 수도 있어 유의
  • -1 리턴 시 ⇒ 양의 정수로는 255로 255를 종료 코드로 전달