본문 바로가기

Operating System [OS]

[OS] 02. Processes

Process

프로세스 = 실행 중인 프로그램

Process = Batch system : jobs = Time-shared system : user programs or tasks)

프로그램은 디스크에 저장된 passive entity(exe file)이며 프로세스는 active

프로그램이 메모리에 로딩돼서 실행되면 하나의 프로세스가 됨

하나의 프로그램이 여러 프로세스가 될 수 있음

프로그램의 실행은 마우스 클릭, 명령어 입력, 터치, 음성 등으로 시작

 

C 프로그램의 메모리 배치

Text Section : 프로그램 코드
현재 활동은 Program counter, Process register를 포함
Stack : 일시적인 데이터 (함수 파라미터, 반환 주소, 지역 변수) - Data : 글로벌 변수, 정적 변수, 상수
Heap : 동적으로 할당되는 메모리
main 함수의 파라미터는 스택 위의 별도 영역에 할당

  • Text : 코드의 크기
  • data : 초기화된 데이터 영역
  • bss : 초기화되지 않은 데이터 영역
  • dec : 위 3개의 합

프로그램을 실행한 상태에서 두 번째 실행하면 메모리에 code(text)는 올라가지 않음
Mac이나 iOS는 2번째 실행해도 각각 코드가 올라가서 최적화되어서 빠르게 실행
Program Counter란?

 ->현재 실행되고 있는 프로세스가 다음에 실행할 명령어의 주소를 가리키고 있는 레지스터
    모든 프로세스마다 필요 (레지스터는 CPU 코어 옆에 존재, 메모리상에 X)


Process State

new : 프로세스가 실행되고 메모리에 올라오기 전
ready : 프로세스가 메모리에 올라옴, OS도 인지, CPU에는 X
running : 명령어가 실행 중인 상태, CPU를 차지, ready 상태에서 OS가 허락하면 CPU로 올라옴
waiting : I/O 이벤트 등 큰 이벤트를 기다리는 상태
terminated : 프로세스가 실행을 완료한 상태, 흔적은 남음

 


Process Control Block (PCB)

  • OS가 프로세스를 관리하기 위해 만들어 놓는 자료구조
  • Process Number : 프로세스의 번호
  • Process State : 프로세스의 상태
  • Program Counter : 한 프로세스의 스레드가 여러 개이면 여러 개가 필요
  • CPU Registers : 모든 프로세스 중심 레지스터의 내용
  • CPU Scheduling Information : 우선순위, 스케줄링 큐 포인터 등
  • Memory 관리 정보 : 프로세스에 할당된 메모리
  • Accounting 정보 : 사용된 CPU, 시작 이후 경과된 시간, 시간 제한
  • I/O 상태 정보 : 프로세스에 할당된 I/O 장치, 열려있는 파일 목록

Context Switch Overhead

CPU Switch From Process to Process

P0이 멈추고 P1이 시작될 때까지의 시간

P0의 PCB를 저장하고 P1의 PCB를 로드하는 시간

 

Linux의 task_struct (C의 구조체로 표현)

mm : memory map 메모리 접근을 어떻게 수행하는지에 대한 정보

time_slice : 한번 CPU를 차지하면 실행되는 시간


Process Scheduling

OS의 목적은 CPU의 활용도를 극대화하는 것 / Time Sharing을 위해 CPU 상의 프로세스를 빠르게 Switch함
Process Scheduler는 현재 Ready 상태인 프로세스 중에서 어떤 것을 CPU에 넘길지 결정하는 것

  • Job Queue : 시스템 내의 모든 프로세스를 모아놓은 큐
  • Ready Queue : 메인 메모리에 상주하고 Ready 상태인 모든 프로세스를 모아놓은 큐
  • Device Queue : I/O 장치를 기다리는 프로세스의 집합, I/O 장치마다 하나의 큐가 있음

 

새 프로세스는 초기에 Ready Queue에 놓인 후, 실행을 위해 선택(Dispatch)될 때까지 Ready Queue에서 기다림
일단 프로세스에 CPU가 할당되면, 아래 사건 중 하나가 발생할 때까지 해당 프로세스가 CPU에서 실행됨
프로세스가 입출력 요청하여 I/O Queue에 넣어짐

인터럽트 또는 할당된 시간 간격이 만료되어 프로세스가 코어에서 강제로 제거되어 준비 큐에 돌아갈 수 있음 (time slice expired)

프로세스가 새 자식 프로세스를 생성하고 자식 프로세스의 종료를 기다리는 동안 대기 큐에 놓일 수 있음 (fork a child)

프로세스가 인터럽트(timer event) 발생을 기다림


Schedulers

Short-term Scheduler (or CPU Scheduler)

  • 다음에 실행될 프로세스를 선택하고 CPU를 할당 (일반적인 Process Scheduling)
  • 밀리초 단위로 자주 호출되며 빠르게 실행되어야 함

Long-term Scheduler (or job Scheduler)

  • Ready Queue에서 (메모리에서) 가져올 프로세스를 선택
  • 초, 분 단위로 드물게 호출되며 느릴 수 있음
  • Multiprogramming의 정도를 제어
  • 프로세스의 좋은 조합을 제공하여야 함

프로세스의 2가지 종류

  • I/O-bound Process : 계산보다 I/O 작업에 더 많은 시간을 소비 / 짧은 CPU burst가 많음 (파일 검색)
  • CPU-bound Process : 계산 작업에 더 많은 시간을 소비 / 긴 CPU burst가 적음 (정렬)

Medium-term Scheduler (Swapping)

  • 다중 프로그래밍 정도를 줄여야 할 필요가 있을 때 추가함
  • 메모리에서 프로세스를 제거하고 디스크에 저장한 후, 디스크에서 메모리로 다시 가져와 실행을 계속함

Context Switch

CPU가 다른 프로세스로 전환될 때, 이전 프로세스의 상태를 저장하고 새 프로세스의 상태를 로드하는 작업
프로세스의 Context는 PCB에 나타남
Context Switch의 시간은 overhead이며 스위칭하는 동안 시스템은 유용한 작업을 하지 않음
복잡한 OS와 PCB는 더 긴 Context Switch가 걸림
하드웨어에 따라 시간이 결정 / CPU당 레지스터가 많으면 여러 Context를 한 번에 로드 가능함


Process Creation

부모 프로세스가 자식 프로세스를 생성, 이 자식 프로세스들은 또 다른 프로세스를 생성 -> 프로세스 트리
일반적으로 프로세스는 Process Identifier(PID)를 통해 식별/관리
Resource sharing 옵션 : 부모와 자식이 모든 리소스 공유 / 자식이 부모 리소스의 일부분 공유 / 공유 X
Execution 옵션 : 부모와 자식이 동시에 실행 / 부모는 자식이 종료될 때까지 대기 (wait 함수)

 

Process Creation 과정

  1. 실행할 수 있는 이진 파일을 Storage에서 메모리로 로드
  2. Runtime Stack 영역 / Heap 영역 할당 (Code랑 Data 영역은 이미 갖고 있음)
  3. I/O 설정 (기본적으로 3개의 파일 디스크립터가 할당 (Standard input, Standard output, Standard error)
  4. OS -> 생성된 프로세스로 제어가 이동하면 main() 함수가 시작

주소 공간

  • 자식이 부모의 주소 공간을 복제
  • 자식은 그 주소에 새 프로그램이 로드된 상태
  • fork()로 복사해서 새 프로세스를 만들고 exec()이 실행되면 자식의 메모리가 덮어써짐
  • system() : fork() + exec() + wait()

Process Termination

프로세스는 마지막 명령을 실행한 후, exit() 시스템 콜을 통해 OS에게 자신을 삭제하도록 요청
자식이 부모에게 상태 데이터를 반환 / OS에 의해 프로세스 리소스가 해제, PCB 해제
부모는 abort() 시스템 콜을 이용해 자식의 실행을 종료할 수 있음

  • 자식이 할당된 리소스를 초과한 경우
  • 자식에게 할당된 작업이 더 이상 필요하지 않은 경우
  • 부모가 종료되고 OS가 자식이 계속되는 것을 허락하지 않는 경우
  • cascading termination : 모든 자식이 종료됨. 종료는 OS에 의해 시작됨 (안정성을 중요시하는 시스템)

부모는 wait() 시스템 콜을 통해 자식이 끝나는 것을 기다릴 수 있음
이 콜은 상태 정보와 종료된 프로세스의 pid 값을 반환
기다리는 부모가 없다면 (wait() 호출을 안 한 경우) -> zombie process (문제가 될 수 있음)

부모가 wait() 호출 없이 종료되었다면 -> orphan process (부모가 없어지면 그 위가 부모가 되므로 문제 X)


Android 프로세스 계층

모바일 운영체제는 제한된 시스템 자원을 회수하기 위해 종종 프로세스를 종료시킴

가장 낮은 순위의 프로세스부터 종료함

 

프로세스의 중요도 계층

  • Foreground 프로세스 : 사용자가 직접 사용
  • Visible 프로세스 : Foreground가 참조하는 활동을 수행하는 프로세스
  • Service 프로세스 : 예시 - 음악 스트리밍
  • Background 프로세스
  • Empty 프로세스 : 프로세스 간의 통신을 할 때 중간 매개체로 활용 (리소스 공유 목적, 명령어는 X)

Interprocess Communication (IPC)

시스템 내의 프로세스는 independent(독립적) or cooperating(협력적)

협력적 프로세스는 다른 프로세스에 영향을 미칠 수 있거나 받을 수 있음

협력적 프로세스는 IPC가 필요

 

협력적 프로세스의 이유

  1. 정보 공유
  2. 계산 속도 향상
  3. 모듈성

협력적 프로세스 모델

  1. Shared Memory
  2. Message Passing
  3. Pipe
  4. (Signal)

공유 메모리 : 속도가 빠름 & 동기화가 필요

메시지 패싱 : 메시지는 헤더, 데이터 등의 포맷이 존재, 속도가 느림

 

Shared Memory

  • 통신을 위해 프로세스 사이에 공유되는 메모리 영역
  • 통신은 OS가 아니라 사용자 프로세스의 제어 아래에서 이루어짐
  • 사용자 프로세스가 공유 메모리에 접근할 때 동기화할 수 있는 메커니즘을 제공하는 것이 중요
  • unbounded-buffer : 버퍼의 크기에 실질적인 제한이 없는 공간
  • bounded-buffer : 고정된 버퍼의 크기를 가정 (write 할 수 있는 공간을 정함)
  • Producer 프로세스는 Consumer 프로세스가 소비하는 정보를 생산

Shared Memory - Producer 프로세스와 Consumer 프로세스

  1. 컴파일러는 어셈블러가 사용하는 어셈블리 코드를 생산
  2. 어셈블러는 목적 모듈(object module)을 생산하고, 이는 로더에 의해 사용
  3. 생산자/소비자 프로세스들은 동시에 수행
  4. 프로세스들은 공유 메모리(버퍼)를 통해 상호 통신
  5. 생산자는 항목(item)을 생산하고 이를 버퍼에 저장
  6. 소비자는 버퍼에 있는 항목(item)을 소비
  7. 가용한 항목이 있을 때만 소비자 프로세스가 소비할 수 있도록, 소비자-생산자 프로세스는 동기화 필요

Shared Memory - 공유 버퍼 (Bounded-Buffer)

  • 두 개의 논리적 포인터인 in과 out을 갖는 원형 배열로 구현
  • (BUFFER_SIZE-1)개보다 많은 원소를 저장할 수 없음 (full/empty의 구분을 위해)
  • 공백(empty) : when in == out (Consumer 공백이면 잠시 멈춤)
  • 가득 참(full) : when (in+1)&BUFFER_SIZE == out (Producer가 가득 차면 잠시 멈춤)

Message Passing

  • 프로세스가 통신하고 작업을 동기화하는 메커니즘
  • 프로세스가 공유된 변수를 사용하지 않고 서로 통신
  • 작업 종류 : send & receive / 메시지의 크기 : 고정 & 가변
  • 두 프로세스가 통신하기 위해서는 그들 사이의 통신 링크 구현, send/receive 메시지 교환이 필요
  • 통신 링크의 구현 : 특정 메모리 공간을 메시지 큐로 잡아주는 과정
     - 물리적 : 공유 메모리, 하드웨어 버스(주로 I/O 기기), 네트워크
     - 논리적 : 직접 / 간접, 동기화 / 비동기화, 자동 버퍼링 / 명시적 버퍼링

Message Passing - Direct Communication

  • 프로세스는 명시적으로 서로 이름을 붙임
     - send(P, message) : P에게 메시지를 보냄
     - receive(Q, message) : Q로부터 메시지를 받음
  • 통신 링크의 속성
     - 링크는 자동으로 설정 / 링크는 정확히 한 쌍의 통신 프로세스와 연관
     - 각 쌍 사이에 정확히 하나의 링크가 존재 / 링크는 단방향일 수 있지만 일반적으로 양방향

Message Passing - Indirect Communication

  • 메시지를 메일박스(혹은 포트)로 보내고 받음 / 각 메일박스는 고유 id를 가짐
  • 프로세스는 그들이 메일박스를 공유할 때만 통신 가능
  • 통신 링크의 속성
     - 링크는 프로세스들이 같은 메일박스를 공유할 때만 설정 / 링크는 많은 프로세스와 관련될 수 있음
     - 각 프로세스 쌍은 여러 통신 링크를 공유 가능 / 링크는 단방향, 양방향 모두 가능
  • 연산 : 새 메일박스 생성 / 메일박스를 통한 send, receive / 메일박스 파괴
     - send(A, message) : 메일박스 A로 메시지를 보냄
     - receive(A, message) : 메일박스 A로부터 메시지를 받음
  • 3개의 프로세스가 한 메일박스를 공유할 때, P1이 보낸 메시지는 P2, P3 중에 누가 받는가?
     - 하나의 링크가 최대 2개의 프로세스와 관련될 수 있도록 허용
     - 한 번의 하나의 프로세스만 수신 작업을 실행하도록 허용
     - 시스템이 수신자를 임의로 선택하도록 허용, 송신자에게 수신자가 누구인지 알림

Message Passing - 메시지 패싱 방식

  • Blocking : 동기화
     - Blocking Send : 메시지가 수신될 때까지 송신자는 차단
     - Blocking Receive : 메시지가 사용 가능할 때까지 수신자를 차단
  • Non-blocking : 비동기화
     - Non-blocking Send : 송신자는 메시지를 보내고 계속 진행
     - Non-blocking Receive : 수신자는 가능한 메시지 혹은 null 메시지를 수신
  • 다양한 조합이 가능 / send, receive 모두 blocking 상태이면 랑데부(rendezvous) 발생

Buffering

  • Zero capacity : 큐에 메시지가 들어가지 않고 송신자는 수신자를 기다려야 함 (랑데부) (Blocking send/receive)
  • Bounded capacity : 유한한 길이의 큐 / 송신자는 링크가 가득 찼으면 기다려야 함
  • Unbounded capacity : 무한한 길이의 큐 / 송신자는 기다리지 않음

Pipes

프로세스 사이의 통신을 가능하게 하는 역할

  • 단방향 or 양방향
  • 양방향인 경우, half-duplex or full-duplex (서로 주고받을 때 한쪽만 가능한지 양쪽 모두 가능한지)
  • 통신하는 프로세스 사이에 관계(부모-자식)가 필요한가?
  • 파이프를 네트워크상에서 사용 가능한가?

Ordinary pipes

  • 생성한 프로세스 외부에서 접근 불가능, 일반적으로 부모가 생성하고 자식과 통신하는데 사용
  • 표준적인 생산자-소비자 스타일의 통신 가능
  • 부모-자식의 관계가 필요
  • 단방향 통신 -> fd[1]에서 쓰기 / fd[0]에서 읽기
  • Windows에서는 익명 파이프(anonymous pipes)라고 부름

Named pipes

  • 부모-자식 관계가 필요하지 않음
  • 양방향 통신
  • 여러 프로세스가 Named pipe를 이용하여 통신 가능
  • UNIX와 Windows 모두 제공

FIFO in UNIX

  • mkfifo()로 생성, open(), read(), write(), close() - Named pipes on Windows
  • byte- or message-oriented data 지원
  • CreateNamePipe(), ReadFile(), WriteFile()

'Operating System [OS]' 카테고리의 다른 글

[OS] 06. Threads & Concurrency  (2) 2024.01.02
[OS] 05. Virtual Memory  (2) 2024.01.02
[OS] 04. Main Memory  (2) 2024.01.02
[OS] 03. CPU Scheduling  (3) 2024.01.01
[OS] 01. Operating System Structures  (1) 2023.12.29