📚 Study

[Operating System] 프로세스와 스레드

date
Aug 20, 2024
slug
os-process-and-thread
author
status
Public
category
📚 Study
tags
운영체제
스레드
summary
프로세스, 스레드, 멀티태스킹, 멀티스레딩, 멀티프로세싱, 멀티프로그래밍, … 이게 다 뭐야!
type
Post
thumbnail
스크린샷 2024-08-19 오후 8.15.48.png
 
 
목차
 

들어가기에 앞서

동시성 Concurrency

  • 한 순간에 여러 가지 일이 일어나는 것이 아님
  • 짧은 전환으로 여러 가지 일을 동시에 처리하는 것처럼 보이는 것

병렬성 Parallelism

  • 실제로 동시에 작동되는 것
 

프로세스와 스레드

✨프로세스 Process

  • 프로그램 = 컴퓨터가 실행할 수 있는 명령어들의 집합
  • 프로세스 = 컴퓨터에서 실행 중인 프로그램의 인스턴스, 각각의 프로세스는 독립된 메모리 공간을 할당 받음
  • CPU = 명령어를 실행하는 연산장치
  • 메인 메모리 = 프로세스가 CPU에서 실행되기 위해 대기하는 곳
프로그램
프로세스
어떤 작업을 하기 위해 실행할 수 있는 파일
실행되어 작업중인 컴퓨터 프로그램
파일이 저장 장치에 있지만 메모리에는 올라가 있지 않은 정적인 상태
메모리에 적재되고 CPU 자원을 할당받아 프로그램이 실행되고 있는 상태
쉽게 말해 그냥 코드 덩어리
그 코드 덩어리를 실행한 것
 

단일 프로세스 시스템

  • 한 번에 하나의 프로그램만 실행됨
  • 단점 = CPU 사용률이 좋지 않음(IO 작업 중에는 CPU가 쉬는 시간이 생김)
 

멀티 프로그래밍

  • 여러 개의 프로그램을 메모리에 올려두고 동시에 실행시키자
  • IO작업이 발생하면 다른 프로세스가 CPU에 의해 실행됨
  • CPU 사용률 극대화가 목적
  • 단점 = CPU 사용 시간이 길어지면 다른 프로세스는 계속 대기
 

멀티 태스킹

  • 프로세스가 한 번 CPU를 사용할 때는 아주 짧은 시간(=quantom)만 사용하도록 하자
  • 멀티프로그래밍 + CPU 시간을 아주 짧게
  • 프로세스의 응답 시간을 최소화 시키는 것이 목적 ⇒ 유저가 느끼기에 여러 프로그램이 동시에 실행된다는 느낌을 주게 됨
  • 한계
    • 여러 프로세스 동시 실행 OK, 하지만 하나의 프로세스가 동시에 여러 작업을 수행하지는 못함
    • 프로세스의 컨텍스트 스위칭은 무거운 작업
    • 프로세스간 데이터 공유가 까다로움
 
그래서 등장한 것이…
 

스레드 Thread

  • CPU에서 실행되는 단위(unit of execution)
  • 프로세스는 한 개 이상의 스레드를 가질 수 있다
  • 같은 프로세스 내부의 스레드끼리의 컨텍스트 스위칭은 가볍다!!
  • 스레드는 자신들이 속한 프로세스 메모리 영역을 공유함(코드 데이터 힙 영역 공유, 스택 제외)
  • ⇒ 장점
    • 캐싱 적중률 올라감, 컨텍스트 스위칭 가벼움, 스레드간 데이터 공유가 쉬움
 

프로세스와 스레드의 메모리구조

프로세스의 메모리 구조

notion image
  • 코드 영역(Code, Text) - 코드가 기계어 형태로 저장되어 있음
  • 데이터 영역(Data) - 코드가 실행되면서 사용하는 전역 변수 등의 데이터
  • 힙 영역(Heap) - 생성자, 인스턴스와 같이 동적으로 할당되는 데이터
  • 스택 영역(Stack) - 지역 변수, 호출한 함수가 종료되면 되돌아올 임시 자료 등을 저장하는 독립적인 공간, 함수의 호출과 함께 할당되며, 함수 호출이 완료되면 소멸
 

각 프로세스는 독립된 메모리 공간을 가짐

notion image
 

스레드의 경우, 프로세스의 자원을 공유하며 독립된 스택 영역을 가짐

notion image
notion image
 

프로세스간 자원 공유 방법은 없을까?

  • IPC(Inter-Process Communication) 사용
  • LPC(Local inter-Process Communication) 사용
  • 별도로 공유 메모리를 만들어서 정보를 주고받도록 설정
 

멀티프로세스와 멀티스레드

  • 멀티 스레드
    • 하나의 프로세스가 동시에 여러 작업을 실행
    • 확장된 멀티 태스킹 개념 = 여러 스레드가 아주 짧게 쪼개진 cpu time을 나눠 갖는 것
  • 멀티 프로세스
    • 두 개 이상의 프로세서나 코어를 활용하는 시스템
    • 처리 방식의 일종, 한 어플리케이션에 대한 처리방식
    • 멀티프로세스 ≠ 여러 개의 어플리케이션을 띄워놓은 것
      • 각 프로세스가 독립적인 영역 가짐, IPC 통한 통신, 자원 소모적, 개별 메모리 차지, 컨스 비용 큼, 동기화 필요 X
    • 멀티스레드
      • 스레드간 긴밀한 연결, 공유자원으로 통신 비용 절감, 공유 자원으로 메모리 효율적, 컨스 비용 적은, 공유 자원 관리 필요
    • 멀스가 더 좋아보이는데 멀티프로세스를 이용하는 이유?
      • 하나의 스레드가 에러나면 다 죽어!
    • 좀더 하드웨어 측면에 가까움
    • 동시성과 병렬성
notion image
 

멀티프로세서와 멀티코어

  • 코어
    • CPU 내부의 일꾼, 각종 연산을 하는 핵심요소
    • 싱글코어, 듀얼코어, … 코어가 많아질수록 일반적으로 처리속도가 빨라짐
  • 프로세서
    • 오늘날 CPU를 대체하는 용어
 
멀티 코어
멀티 프로세서
프로그램 명령을 읽고 실행할 수 있는 코어라고 하는 두 개 이상의 독립적인 처리 장치를 갖춘 단일 CPU 또는 프로세서
프로그램을 동시에 처리할 수 있는 두 개 이상의 CPU가 있는 시스템
단일 프로그램을 더 빠르게 실행
여러 프로그램을 더 빠르게 실행
멀티프로세서만큼 안정적이지 않음
한 CPU에 장애가 발생해도 다른 CPU에는 영향을 미치지 않으므로 더욱 안정적
트래픽이 적음
트래픽이 더 많음
구성할 필요가 없음
복잡한 구성이 거의 필요하지 않음
매우 저렴(다중 CPU 지원 시스템이 필요하지 않은 단일 CPU).
멀티코어에 비해 비용이 많이 듦(여러 프로세서를 지원하는 시스템이 필요한 여러 개의 개별 CPU가 필요함).
  • 멀티코어와 멀티프로세서의 유일한 공통점은 처리 속도를 높이는 것
  • 멀티코어 시스템의 비용은 멀티프로세서 시스템에서 더 많은 물리적 프로세서를 사용하기 때문에 멀티프로세서 시스템 비용에 비해 저렴
  • 처리 속도 (큰 쪽이 빠름)단일 프로그램을 실행 -> 멀티코어 시스템 > 멀티프로세서 시스템여러 프로그램을 실행 -> 멀티프로세서 시스템 > 멀티코어 시스템
  • 최신 컴퓨터에는 각각 여러 개의 코어를 가진 여러 개의 CPU 존재
 

예제

아래 상황에 대하여 멀티태스킹 / 멀티스레딩 / 멀티프로세싱 OX 생각해보기
싱글코어 CPU에 싱글 스레드 프로세스 두개
  1. 멀티태스킹 O
  1. 멀티스레딩 X
  1. 멀티프로세싱 X
싱글코어 CPU에 듀얼 스레드 프로세스 한개
  1. 멀티태스킹 O
  1. 멀티스레딩 O
  1. 멀티프로세싱 X
듀얼코어 CPU에 싱글 스레드 프로세스 두개
  1. 멀티태스킹 X
  1. 멀티스레딩 X
  1. 멀티프로세싱 O
듀얼코어 CPU에 듀얼 스레드 프로세스 한개
  1. 멀티태스킹 X
  1. 멀티스레딩 O
  1. 멀티프로세싱 O
듀얼코어 CPU에 듀얼 스레드 프로세스 두개
  1. 멀티태스킹 O
  1. 멀티스레딩 O
  1. 멀티프로세싱 O
 

요약

  • 프로세스는 프로그램이 실행된 것이다
  • 스레드는 한 프로세스 내에서 나뉘어진 하나 이상의 실행 단위이다
  • 한 어플리케이션에 대한 작업을 동시에 하기 위해서 2가지 처리 방식(멀티 프로세스, 멀티 스레드)이 있다
  • 동시에 실행되는 것처럼 보이기 위하여 실행단위는 시분할로 cpu를 점유하며 컨텍스트 스위칭 한다
  • 멀티 프로세스는 독립적인 메모리를 가지고 있지만, 멀티 스레드는 자원을 공유한다. 각각의 장단점이 있다
 

질문

프로세스와 스레드에 대해 설명해보세요.
  • 프로세스란 실행중인 프로그램 인스턴스이고, 스레드란 프로세스 안에서 실행되는 작업 단위입니다.
  • 프로세스는 메모리와 CPU를 할당받아 사용하는데 스레드는 프로세스 안에서 다른 스레드와 메모리와 CPU를 공유하고 고유한 stack 메모리만을 각자 할당받습니다.
동시성과 병렬성에 대해 설명해보세요.
  • 동시성은 여러 작업이 같은 시간대에 실행되는 것처럼 보이게 하는 것이고, 병렬성은 여러 작업이 실제로 동시에 실행되는 것입니다.
스레드간 컨텍스트 스위칭은 항상 가벼울까요?
  • 같은 프로세스의 스레드 간 컨텍스트 스위칭은 프로세스 컨텍스트 스위칭보다 가볍지만, 다른 프로세스의 스레드간 컨텍스트 스위칭은 사실상 프로세스 컨텍스트 스위칭과 같으므로 가볍지 않습니다.
멀티스레드가 멀티프로세스보다 항상 좋을까요? 둘 중 하나를 선택해야 한다면 어떤 기준으로 판단해야 할지?
  • 멀티 스레드는 멀티 프로세스보다 적은 메모리 공간을 차지하고 컨텍스트 스위칭이 빠르다는 장점이 있지만, 오류로 인해 하나의 스레드가 종료되면 전체 스레드가 종료될 수 있다는 점과 동기화 문제, 데이터 경합 문제를 가지고 있습니다.
  • 반면, 멀티 프로세싱 방식은 하나의 프로세스가 죽더라도 다른 프로세스에는 영향을 끼치지 않고 정상적으로 수행된다는 장점이 있지만, 멀티 스레드보다 많은 메모리 공간과 CPU 시간을 차지한다는 단점이 존재합니다.
  • 이 두 가지는 동시에 여러 작업을 수행한다는 점에서 같지만 적용해야 하는 시스템에 따라 적합/부적합이 구분되므로 대상 시스템의 특징에 따라 적합한 동작 방식을 선택하고 적용해야 합니다.
  • 만약 작업의 안전성을 보장하고 싶다면 멀티프로세싱을, 안전성보다는 성능과 응답시간을 보장하고 싶다면 멀티스레딩을 선택하는 것이 좋을 것 같습니다.
스레드를 많이 쓸수록 성능이 좋아질까요?
  • 스레드를 많이 사용하는 것이 항상 성능 향상으로 이어지지는 않으며, 오히려 오버헤드나 경쟁 상태가 발생해 성능이 저하될 수 있습니다.
Stack 메모리를 스레드마다 독립적으로 할당하는 이유는?
  • 각 스레드가 독립적인 함수 호출과 로컬 변수를 가질 수 있도록 하기 위해 스택 메모리를 독립적으로 할당합니다.
  • 즉, 스레드의 정의에 따라 독립적인 실행 흐름을 추가하기 위한 최소 조건으로 독립된 스택을 할당합니다.
PC 레지스터를 스레드마다 독립적으로 할당하는 이유는?
  • PC 레지스터 값은 스레드가 명령어의 어디까지 수행했는지를 나타냅니다. 스레드는 CPU를 할당받았다가 스케줄러에 의해 다시 선점당하기 때문에 명령어가 연속적으로 수행되지 못하고 어느 부분까지 수행했는지 기억할 필요가 있습니다. 따라서 PC 레지스터를 각 스레드에 독립적으로 할당합니다.
“리눅스에서는 프로세스와 스레드가 같다” 의 의미?
  • 리눅스 커널에서는 프로세스와 스레드를 동일하게 봅니다
  • 리눅스는 1:1 모델
    • ⇒ 어차피 각각의 프로세스가 하나의 스레드다, 혹은 스레드도 사실상 경량 프로세스이다
    • ⇒ 프로세스와 스레드가 같은 주소 공간을 공유하는 프로세스로 취급됨
    • PID, TID(스레드 아이디)
사용자 수준의 스레드와 커널 수준의 스레드의 차이는 무엇인가요?
  • 관리 주체:
    • 사용자 수준 스레드: 사용자(프로그램) 공간에서 관리되며, 커널은 이를 인식하지 못함.
    • 커널 수준 스레드: 운영 체제의 커널이 스레드를 직접 관리하고 스케줄링함.
  • 장점:
    • 사용자 수준 스레드: 컨텍스트 스위칭이 빠르고, 플랫폼 독립적.
    • 커널 수준 스레드: 진정한 병렬 처리 가능, 효율적인 자원 관리.
  • 단점:
    • 사용자 수준 스레드: 블로킹 문제 발생 가능, 병렬 처리 불가능.
    • 커널 수준 스레드: 컨텍스트 스위칭이 느리고, 커널 오버헤드 증가.
스프링 프레임워크는 멀티스레딩과 멀티프로세싱 중 어떤 걸 사용하나요?
  • 스프링은 주로 멀티스레딩을 사용하여 동시성을 처리합니다.
  • 서블릿 컨테이너: 스프링 애플리케이션은 보통 서블릿 컨테이너(Tomcat, Jetty 등) 위에서 실행됩니다. 서블릿 컨테이너는 각 HTTP 요청을 별도의 스레드에서 처리합니다. 이 방식으로 동시에 여러 요청을 처리할 수 있습니다.
  • @Async 어노테이션: 스프링은 @Async 어노테이션을 사용하여 비동기적으로 실행될 메서드를 지정할 수 있습니다. 이 경우 스프링은 스레드 풀(Thread Pool)에서 스레드를 할당하여 비동기 작업을 수행합니다.
  • 스레드 풀(Thread Pool): 스프링에서는 TaskExecutor를 사용해 스레드 풀을 관리할 수 있습니다. 스레드 풀은 미리 일정 수의 스레드를 생성해 두고, 작업이 요청될 때마다 스레드를 재사용함으로써 스레드 생성과 소멸의 오버헤드를 줄여줍니다.
  • 스프링 스케줄러: 스프링은 @Scheduled 어노테이션을 사용하여 주기적으로 실행될 작업을 정의할 수 있습니다. 이 경우에도 스레드 풀이 사용되어 멀티스레딩 방식으로 스케줄링 작업이 실행됩니다.
  • 고려사항: 스레드 간의 자원 공유로 인해 동기화 문제가 발생할 수 있습니다. 따라서, 스레드 안전(Thread-safety)을 유지하기 위한 고려가 필요하며, 잘못된 동기화는 데드락(Deadlock)이나 경쟁 조건(Race Condition)을 초래할 수 있습니다.
 

출처