CS/운영체제

[공룡책🦖] 프로세스

설기똥꼬 2023. 7. 11. 15:36

본 포스팅은 공룡책으로 불리는 Abraham Silberschatz, Peter B. Galvin, Greg Gagne의 『Operating System Concept 10th』 기반으로 정리한 글입니다.


Process Concept

프로세스란?

  • 실행 중인 프로그램
  • OS의 작업 단위
  • 하나의 프로세스가 실행되기 위해 자원 필요
    • CPU, memory, files, I/O devices

 

프로세스 상태 정보는 (1) program counter와 (2) contents of the processor's register로 구성

 

 

프로세스 레이아웃

  • Text section ⇒ 명령어 실행 코드
  • Data section ⇒ 전역 변수들
  • Heap section ⇒ 함수 호출시 dynamic하게 저장되는 메모리
  • Stack section ⇒ 함수 파라미터, 리턴되는 주소나 지역 변수를 저장하는 일시적 데이터 저장

 

  • Text와 Data 부분은 고정
  • Stack와 Heap 부분은 동적
    • Stack은 grow down
    • Heap은 grow up

⇒ 겹치지 않게 OS가 조절

 

프로세스 레이아웃 예시

 

Program and Process

  • program : 디스크에 저장된 명령어 리스트를 포함하는 파일 (executable file)
  • process : 다음 실행할 명령어를 나타내는 program counter와 관련 자원 집합을 가짐
    • 두 process가 동일 program과 관련되더라도 두 개의 독립된 실행 순서로 간주됨 이 경우 Text section은 동일하고 나머지는 다름

 

 

Process State

  • New : 프로세스가 막 생성된 상태
  • Running : CPU가 프로세스를 점유하여 프로세스를 로딩하는 상태
  • Waiting : 다른 프로세스가 CPU를 점유할 때 
  • Ready : I/O 대기하고 있다가 점유할 준비, 대기중
  • Terminated : 프로세스 실행 끝남

 

processor core에서 실행될 수 있는 process는 오직 한 번에 한 개뿐이지만, ready나 waiting 상태는 많은 process들이 존재할 수 있다.

 

 

Process Control Block (PCB)

PCB는 구조체 내 프로세스가 가져야하는 모든 정보들을 저장하는 저장소이다.

프로세스마다 각각 PCB를 가지며 이는 doubly linked list로 구현된다.

각 프로세스가 가져야하는 모든 정보들을 저장한다.

 

  • Process state : new/running/ready/waiting/halted 등
  • Program counter : 다음 명령어의 주소
  • CPU registers : interrupt 발생 시 PC와 함께 상태 정보 저장하여 reschedule 후 계속 실행됨
  • Memory-management information 
  • Accounting information
  • I/O status information

 

 

Threads

Single thread of execution

  • Process는 single thread를 실행하는 program
    • 현대 OS 프로세스
  • single thread 제어는 한번에 하나의 task만 실행됨 (ex. 문자 입력과 철자 검사를 동시에 X) 

 

Multiple Thread

  • Process가 여러 실행 thread만 가지고 한 번에 하나 이상의 tasks를 실행함
  • Multi core system인 경우 여러 thread가 병렬로 실행 가능
  • Thread 지원 system에서 PCB가 각 thread에 대한 정보를 포함하도록 확장

 

 

Process Scheduling

Multiprogramming

항상 process들이 실행되도록 하여 CPU 이용률을 최대화한다.

 

 

multiprogramming의 목적 

  • 동시에 여러 프로세스 실행
  • CPU 사용률 증가
  • Time sharing으로 프로세스 내 CPU core를 스위치하여 각 프로그램이 동시에 돌고 있는 것처럼 보이도록 함

 

 

Time sharing

Process 사이에서 CPU core를 자주 switch하여 user와 program이 상호작용한다.

→ core에서 프로그램을 실행하기 위해 process scheduler가 실행 가능한 process를 하나 고른다.

 

Single CPU core를 가진 system에서는 한 번에 한 process만 실행 가능하지만, multicore system에서는 multiple processes들이 동시에 실행될 수 있다.

이때 core의 수보다 process의 수가 더 많은 경우 process들이 wait해야 한다.

 

  • multiprogramming과 time sharing의 균형을 위해 적절히 스케줄링 해야한다.
  • 시간 소비에 따라 I/O bound or CPU bound process로 구분된다.

 

Degree of multiprogramming

현재 메모리 내 process 수

 

 

Scheduling Queues

출처 : https://www.tutorialspoint.com/operating_system/os_process_scheduling.htm

  • Process가 system에 진입하여 Ready queue에 삽입되어 대기한다.
  • IO가 있으면 wait queue로 삽입된다.
  • Ready Queue / Wait Queue는 linked list 형태로 저장된다.
  • queue의 head는 첫 PCB 포인터를 가지며, 각 PCB는 다음 PCB에 대한 포인터를 가진다.

 

 

Queueing Diagram

종료 시점에 queue에서 제거되고 PCB와 자원이 해제된다.

https://www.researchgate.net/figure/Queuing-Diagram-for-Scheduling-in-OS_fig1_337448111

 

CPU Scheduling 

process는 ready queue와 wait queue 사이를 이주한다.

 

 

CPU scheduler의 역할

  • ready queue에서 하나의 process를 선택하고 CPU core를 할당한다.
  • I/O bound process → 잠깐 실행 후 I/O 대기
  • CPU bound process → 오랜 기간동안 CPU core가 필요해도 장기간 할당될 가능성은 없음 (CPU를 뺏어서 다른 process에게 스케줄함)

 

Swapping - 메모리 과부하 상태일 때 process 제거

  • memory에서 process를 제거하여 다중화 정도를 낮추는 것
  • 나중에 다시 memory로 적재되어 중단된 위치에서 계속 실행됨
  • swapped out = 메모리 → 디스크
  • swapped in = 디스크 → 메모리
    • 메모리가 초과 사용되어 해제되어야할 때만 필요

 

 

Context Switch (문맥 교환)

  • CPU가 다른 프로세스와 CPU core를 교환하는 것
  • Context : PCB 내 프로세스가 사용되고 있는 상태, PCB로 보면 됨
  • interrupt 발생
    • 실행 중인 프로세스의 현재 context 저장 (PC, 어디까지 저장했는지)
    • OS는 현재 task로부터 CPU core를 뺏아 kernel 루틴을 실행하게 함
    • 다른 프로세스 로딩시 저장한 context를 restore

화살표 = running 상태 / 검은 선 = wait or ready 상태

 

  • 다른 process에게로 CPU core를 switching하는 것
  • PCB에 old process의 문맥을 저장하여 실행될 new process의 saved 문맥을 load

 

 

Operations on Processes

프로세스는 동시에 수행되고 동적으로 생성/삭제된다.

프로세스는 새로운 프로세스를 생성할 수 있다. 부모/자식 프로세스 by fork()

 

 

Process Creation

  • 실행 중에 process는 새로운 process를 생성한다.
    • 생성한 process = 부모 process
    • 생성된 process = 자식 process
  • 부모/자식 process는 병렬적으로 실행
  • 부모는 자식이 종료될 때까지 기다림
  • 자식이 부모의 복제본이면 부모와 동일한 프로그램과 데이터를 가짐 [fork() system call]
  • 자식 process가 자신에게 load되는 새로운 프로그램을 가짐

 

Process identifier (pid)

  • pid로 process를 식별
  • kernel 내에서 다양한 process의 속성에 접근하기 위한 index로 사용

 

command

  • ps -el : 현재 실행 중인 process들의 list를 보여줌
  • pstree : tree로 보여줌

 

systemd process (pid=1)

  • root parent process
  • 모든 user process들의 부모이며 부트 시 생성되는 첫 user process
  • 부팅되면 systemd가 추가적인 서비스를 제공하는 process를 생성함

 

Child process가 자원을 필요로 할 때

  • 자식 process가 OS로부터 직접 자원을 할당받거나 부모 process 자원의 부분집합으로 제한
  • 부모는 자식들 간 자원을 분할하여 사용하거나 자식들과 자원 공유

한 프로세스가 너무 많은 자식을 생성하여 시스템을 과부하시키는 것을 막음

 

 

Child process에 필요한 data 전달

  • OS가 자식 process에게 자원을 전달
  • 부모 process가 자식 process에게 초기화 data 전달

 

 

자식 process

  • 부모로부터 자원뿐만 아니라 특권, 스케줄링 속성을 물려받음
  • exelip()를 이용해 자신의 주소 공간을 ls 명령어로 덮어씀 

 

 

부모 process

  • wait() system call을 이용하여 자식 process가 끝날 때까지 기다림
  • 자식 process 종료 시, 부모는 wait() 호출로부터 재개

 

 

UNIX OS에서의 process 생성 과정

fork() system call : 새로운 process 생성하는 시스템 콜

  • 새로운 process는 original 주소 공간의 복사본으로 구성됨
  • 부모와 자식이 쉽게 통신하게 함
  • pid = for() : 리턴 = (1) 0 (자식) (2) child의 pid (부모)

 

After a fork() system call

  • fork() 후, 한 process가 exec() system call하여 메모리 공간을 새 프로그램으로 교체
  • binary file을 memory로 적재하고 실행함 
    • 적재 : 자신을 포함한 프로그램의 메모리 이미지를 파괴(덮어쓰기)
  • 자식을 더 생성하거나 자식이 실행되는 동안 할 일이 없으면 자식이 종료될 때까지 ready queue에서 자신을 제거하기 위해 wait() system call을 함 

 

 

Process Termination

return(final Statement)로 종료를 명시하거나 exit()로 중도 out처리한다.

OS 입장에서는 메모리 및 자원 해제, 회수한다.

 

 

스스로 종료

  • 마지막 문장을 실행하여 종료하고 exit() system call로 OS에 자신을 삭제 요청
  • wait() system call을 통해 대기 중인 부모 process에 상태값이 반환됨
  • process의 자원들은 OS에 의해 할당이 해제되고 회수됨

 

다른(부모) process에 의한 종료

  • system call로 다른 process를 종료시킴 (TerminateProcess() in Window)
  • 종료시키는 system call은 부모 process로부터 호출됨
  • process 종료를 위해서 부모는 자식의 pid를 알아야함 
    • process 생성 시 부모에게 pid 전달
  • 이유
    • 자식이 할당된 자원을 초과 사용한 경우
    • 자식에게 할당된 task가 더 이상 필요하지 않은 경우 task 종료
    • 부모가 exit시 자식이 계속 실행되는 것을 OS가 허용하지 않은 경우

 

Cascading termination

  • 부모가 종료되면 자식이 존재할 수 없음 → 모든 자식이 종료되어야 함
  • 자식이 종료될 때 pid가 return되어 부모는 어느 자식이 종료됐는지 식별
    • pid = wait(%status) // exit(1) → 1인 status로 종료

 

 

사용자에 의한 종료

 

 

Process Table

PCB의 array는 현재 존재하는 모든 process의 PCB이다. 

→ process의 exit status가 process table에 저장되므로 process table의 항목은 부모가 wait()를 호출할 때까지 남아있어야 한다.

 

 

Zombie Process → 정상 종료 가능

  • 종료되었거나 부모가 아직 wait()를 호출하지 않은 process
    • 자식 할 일 하게 냅워서 자식은 좀비처럼 계속 남아있음
  • 부모가 wait()를 호출하면 좀비의 process pid와 process table의 항목이 해제됨

 

Orphan Process → 정상 종료 불가능

 

  • 부모가 wait()를 호출하지 않고 종료한 경우 PCB에 정보가 계속 남음
  • 이를 System 선에서 정리해야하는데, init process를 orphan process의 새로운 부모로 지정하여 해결
  • int이 주기적으로 wait()를 호출하여 orphan process의 exit status를 수집하고 orphan process의 id와 process table 항목을 해제함

 

 

Interprocess Communication (IPC)

Process 간 협력 이유

  • Information sharing
  • Computation speed up
  • Modularity

 

IPC Model

  1. shared-memory model → 공유 메모리 주고 받음
    • 공유 메모리 영역을 만들 때만 system call이 일어나므로 빠름
    • 공유 메모리가 만들어지면 모든 접근이 일상적인 메모리 접근으로 취급되고 커널 도움 필요 없음
    • process들은 동시에 동일 위치에 쓰지 않도록 책임져야 함
  2. message-passing model → 메세지 주고 받음
    • 작은 data 교환시 유용
    • 분산 system 환경에서 구현 쉬움
    • 느림

 

 

 

IPC in Shared-Memory Systems

  • 공유 메모리 영역은 공유 메모리 segment를 생성하는 process의 주소 공간에 위치
  • 공유 메모리 segment를 사용해 통신하기 원하는 process들은 자신의 주소 공간에 추가
  • process들은 동시에 동일 위치에 쓰지 않도록 책임져야함

 

A solution using shared-memory

producer(정보 생산)와 consumer(정보 소비)는 동시에 실행되고, CPU를 잘 나눠서 점유한다.

  • Complier → assembly code 생산, assembler → assembly code 소비
  • client-server 패러다임
  • 동시에 실행하기 위해 producer는 buffer를 채우고, consumer는 이를 받아 사용함
  • producer와 consumer는 동기화되어야 함 생산되지 않은 정보를 소비하지 않음

 

Buffer

Buffer가 가득차면 Producer는 wait, 아직 모자라면 Consumer는 wait 상태를 유지한다.

  • unbounded buffer : consumer는 item 대기 가능, producer는 계속 생성 가능
  • bounded buffer : consumer는 empty일 때 대기, producer는 full일 때 대기 ⇒ 원형 배열로 구현

 

 

IPC in Message-Passing Systems

Shared-Memory system의 복잡한 내용들을 OS가 처리하게끔 한다! (By cooperating process 수단)

  • 네트워크로 연결된 다른 컴퓨터들의 process간 통신
  • send(message) receive(message)
  • message의 길이는 고정이거나 가변이고, 통신을 원하면 message를 주고 받아야함
    • fixed-sized message : 시스템 수준 구현은 단순하나 task 프로그래밍이 어려움
    • variable-sized message : 시스템 수준 구현은 복잡하나 task 프로그래밍이 쉬움
  • Naming → 통신을 원하는 process들은 서로 통신 상대를 지정해야 

 

Direct  communication (직접 연결 통신)

recipient/sender process의 이름을 명시한다.

  • send(P, message) : process P에게 메세지 전달
  • receive(Q, message) : process Q로부터 메세지 받음
  • P와 Q가 직접적으로 연결됨
    • communication link는 자동으로 생성되고, 하나의 링크만 성립됨

 단점

  • process 정의에서 modularity가 제한됨
  • process id의 변경은 모든 다른 process 정의를 검사해서 변경해야 함
  • id가 직접적으로 명시되는 hard-coding 기법

 

  1. Symmetry in addressing 
    • 통신하려면 둘 다 상대의 이름을 지정
  2. Asymmetry in addressing
    • sender만 recipient를 naming
    • send(P, message)
    • receive(id, message) : any process로부터 받음 (id는 통신이 일어난 process의 이름)

 

Indirect communication (간접 연결 통신) - mailbox

  • mailbox는 process들이 메세지를 저장(send)하고 제거(receive)하는 객체
  • 두 process가 공유 mailbox를 가질 때만 통신 가능
  • 여러 mailbox를 통해 다른 process들과 통신
  • send(A, message), receive(A, message) : mail box A를 통해서 통신

 

둘 이상의 process가 같은 mailbox를 공유하는 경우

  • link가 최대 두 process만 연관되도록 제한
  • 최대 한 번에 한 process만 receive()
  • 어떤 process가 메세지를 receive할 지 선택 (round robin)

 

mailbox 소유

  1. process 소유 
    • 소유자(수신자)와 사용자(송신자)로 구분
    • 각 mailbox마다 고유한 owner가 있음
    • mailbox를 갖는 process가 종료되면 mailbox도 사라짐
    • 사라진 mailbox에 메세지를 보내는 process는 mailbox가 없음을 통보받음
  2. OS 소유
    • 독립적으로 존재하여 특정 process에 속하지 않음
    • process가 mailbox를 생성/삭제하는 기능을 OS가 제공
    • mailbox를 생성하는 process가 owner
    • mailbox에 대한 권한은 system call로 다른 process에 전달 가능

 

 

Synchronization 동기화

  • process 간 통신은 send() / receive() 호출로 발생
  • blocking (synchronous) Send : 수신될 때까지 send 대기 → 수신 후 송신
    • 메세지가 받아들여질 때까지 sender는 블락됨
  • blocking (synchronous) Receive : 메세지가 avail할 때까지 receive 대기 → 송신 후 수신
    • 메세지 available할 때까지 receiver는 블락됨
  • nonblocking (asynchronous) Send, Receive
    • sender가 메세지 보내고 할 일 계속함
    • receiver가 유효하거나 빈 메세지를 되찾아옴 (Retrieve)

⇒ send와 receive의 종류에 따라 4가지 조합 가능

 

 

Buffering 

  • 메세지는 temporary queue에 보관

 

Queue 세 가지 구현 방법

  • Zero capacity : 보관 X
  • Bounded capacity : N개 메세지 보관
  • Unbounded capacity : 무한개 보관