Skip to content

Latest commit

 

History

History
118 lines (108 loc) · 8.44 KB

process.md

File metadata and controls

118 lines (108 loc) · 8.44 KB

전체적인 흐름


  • 프로그램(실행 가능한 파일)은 하드디스크 파일 시스템에 실행파일 형태로 저장
  • 이 파일을 실행시키면 프로세스가 됨 -> 가상 메모리를 거쳐 물리적 메모리로 올라가면 CPU를 할당받아 실행될 수 있음
  • 프로세스마다 주소 공간(Address space)를 가짐
    • 커널 영역은 컴퓨터를 키면 항상 메인 메모리에 올라가있음 / 사용자 프로그램은 프로그램이 종료되면 해당 프로세스의 주소 공간이 사라짐
    • 주소 공간에서 당장 필요한 부분은 물리적 메모리에, 그렇지 않은 부분은 디스크의 swap area에 저장됨
  • file system과 swap area은 둘 다 하드디스크지만 사용 용도가 다름
    • file system : 비휘발성의 용도 (전원이 나가도 파일의 내용이 유지되어야하기 때문에 사용)
    • swap area : 메모리 연장 공간의 용도

프로세스

  • 프로세스 : 실행 중인 프로그램
  • 프로세스의 문맥 (context) : 프로세스가 어느 지점까지 실행했는지 나타냄
    • 프로세스들이 CPU를 번갈아 사용하기 때문에 프로세스가 어느 지점까지 실행되었는지 정확하게 알아야함
    • 1)CPU 수행 상태를 나타내는 하드웨어 문맥 (프로세스가 명령어를 어디까지 실행했는가)
      • Program Counter (PC가 어딜 가리키고 있는가) / 각종 register (레지스터에 어떤 값이 저장되었는가)
    • 2)프로세스의 주소 공간
      • code, data, stack, heap (프로세스의 주소 공간에 어떤 값이 저장되었는가)
    • 3)프로세스 관련 커널 자료 구조
      • PCB(Process Control Block) / 커널 스택 (프로세스마다 생성하고 관리)

프로세스의 주소 공간


  • data 영역 : 프로그램 실행 시 할당되며 프로그램 종료 시 소멸됨
  • stack 영역 : 함수 호출 시 할당되며 함수 종료 시 소멸됨
  • heap 영역은 사용자에 의해 동적으로 메모리를 할당되기 때문에 속도는 stack이 더 빠름

프로세스의 상태


  • Running : CPU 제어권을 가지고 명령어를 수행 중인 상태 / running 상태의 프로세스는 매 순간 하나!
  • Ready : 다른 모든 조건을 만족하고 CPU만 얻으면 명령어를 수행할 수 있는 상태
  • waiting(blocked) : CPU를 주어도 당장 명령어를 수행할 수 없는 상태 (ex. I/O 작업 완료를 기다리는 중)
  • new : 프로세스가 생성중인 상태
  • terminated : 프로세스 수행이 끝난 상태

PCB (Process Control Block)

  • 운영체제가 각 프로세스를 관리하기 위해 프로세스에 대한 정보를 저장하는 자료구조
  • 프로세스가 하나 생길 때마다 운영체제는 커널 주소 공간의 data영역에 PCB를 생성
  • 구성 요소
    • 운영체제가 관리상 사용하는 정보 : Process state / Process ID / scheduling information / priority
    • CPU 수행 관련 하드웨어 값 : Program counter / registers
    • 메모리 관련 : code, data, stack의 위치 정보

문맥 교환 (context switching)


  • CPU를 한 프로세스A(스레드)에서 다른 프로세스B(스레드)로 넘겨주는 과정
  • 현재 CPU의 PC, 레지스터 값을 읽어서 뺏기는 프로세스의 PCB에 저장
  • 실행할 프로세스의 PCB의 값을 읽어서 CPU에 복원
  • context switching이 발생하는 경우
    • I/O 작업 / CPU 사용 시간 만료 (타이머) / 인터럽트

프로세스와 관련된 시스템 콜

  • fork() : 자식 프로세스를 복제 생성하는 시스템 콜
  • exec() : 프로세스를 완전히 새로운 프로그램으로 덮어 씌우는 시스템 콜
  • wait() : 자식 프로세스가 종료될 때까지 잠들어서 기다리는 시스템 콜
  • exit() : 자식 프로세스가 모든 자원을 반납하고 부모 프로세스에게 알리는 시스템 콜

IPC (Inter Process Communication)

  • 프로세스마다 메모리가 독립적으로 할당 -> 프로세스끼리 메모리 접근 불가능
  • 운영체제에서 프로세스의 주소공간을 보호하는 동시에 프로세스간 서로 데이터를 주고 받는 방법을 제공 = IPC
  • 1)PIPE
    • 파이프로 두 개의 프로세스를 연결하여 데이터를 전달 (하나는 데이터 쓰기만, 하나는 읽기만 수행)
    • 통신할 프로세스를 명확히 아는 경우 사용 ex) 부모와 자식 프로세스간 통신
    • 매우 간단 / 양방향 통신을 할 수 없음
  • 2)Named PIPE (FIFO)
    • 이름이 있는 파일을 사용하기 때문에 전혀 모르는 상태인 프로세스들 사이의 통신인 경우 사용
  • 3)message queue
    • 파이프는 데이터의 흐름 / 메시지 큐는 메모리 공간
    • 여러 프로세스가 메시지 큐에 있는 데이터를 동시에 쉽게 다룰 수 있음
  • 4)shared memory
    • 통신을 이용해서 데이터를 주고받는 것이 아니고 프로세스간 메모리 영역을 공유해서 데이터를 함께 사용
    • 중개자없이 바로 메모리에 접근할 수 있기 때문에 IPC 중에서 가장 빠름
  • 5)socket

스레드

  • 프로세스 내에서 CPU 수행 단위
  • 프로세스 내에서 공유할 수 있는 것은 최대한 공유하고 CPU 수행과 관련있는 것은 따로 할당받아 관리
  • 각 스레드마다 따로 관리하는 부분
    • program counter (독립적인 실행을 위해 어느 명령어까지 실행했는지 저장)
    • registers
    • stack (독립적인 함수 호출을 위해)
  • 다른 스레드와 공유하는 부분
    • code / data / heap / 다른 운영체제 자원들

커널 레벨 vs 유저 레벨

  • 커널 레벨 스레드
    • 커널 레벨에서 제공하는 스레드 -> 안전함
    • 커널이 스레드의 존재를 알고 각 스레드의 실행을 관리 (스레드 스케쥴링)
    • 스레드간 context switching마다 커널이 일을 해야함 -> 커널 모드로 바꿔야함 -> 느림
  • 유저 레벨 스레드
    • 유저가 라이브러리를 통해 만들어서 사용하는 스레드
    • 커널은 스레드의 존재를 모르고 프로세스를 관리 (프로세스 안에서 유저 레벨 스레드가 동작)
    • 스레드간 context switching시 커널 모드로 바꾸지 않아도 됨 -> 커널 레벨 스레드보다 빠름!!
  • 스레드A가 I/O 블로킹 상태에 빠졌다면?
    • 커널 레벨 스레드
      • 스케쥴러가 다른 스레드에게 실행권을 넘겨줌
    • 유저 레벨 스레드
      • 스케쥴러는 스레드A의 존재를 모르기 때문에 프로세스A가 블로킹 상태라 판단
      • 프로세스B에게 실행권을 넘겨줌
      • 프로세스A안에 스레드A와 스레드B가 있다면 스레드B는 실행 불가능
      • 즉, 스레드 하나가 블로킹되면 프로세스 전체가 블로킹 상태에

multi-thread VS multi-process

  • multi-process
    • 여러 개의 프로세스가 작업을 동시에 처리
    • 단점) context switching 비용이 크다 (각각 독립적인 메모리를 가지고 있기 때문) / 프로세스 간 통신을 하려면 IPC
    • 자식 프로세스 중 하나가 문제가 생겨도 다른 프로세스에 영향이 없음 (독립적으로 동작)
  • multi-thread
    • 하나의 프로세스 안에서 여러 개의 쓰레드가 처리
    • context switching 비용이 적음 (프로세스 자원을 공유하기 때문)
    • 단점1) 하나의 스레드가 종료되면 전체 스레드가 종료
    • 단점2) 자원을 공유하는 만큼 충돌 주의 (thread-safe 하게) -> 동기화 / 동기화 처리로 인한 병목 현상이 발생하여 성능 저하
  • multi-thread가 multi-process보다 좋은 이유
    • context switching시 오버헤드가 적음
    • stack을 제외한 모든 메모리를 공유하기 때문에 자원을 효율적으로 사용 가능
    • BUT 동일한 메모리 공간을 공유하기 때문에 동기화 문제 발생 가능