스레드와 스레드 풀

김민재·2024년 12월 28일
0

프로세스와 스레드 간단 요약

프로세스 - 프로그램을 실행하는 주체
스레드 - 작업을 처리하는 주체

프로세스와 스레드의 차이점

프로세스: 자신만의 고유 공간과 자원을 할당 받아 사용

  • 프로세스는 메모리 상에서 실행중인 프로그램, 스레드는 프로세스 안에서 실행되는 흐름 단위를 말한다.
  • 프로세스는 최소 하나의 스레드를 보유, 각각 별도의 주소공간을 독립적으로 할당 받는다(code,heap,stack)

프로세스만으로 작업을 처리할 순 없을까?

  • 프로세스는 생성시에 큰 오버헤드가 있다. => 프로세스는 생성할 때 많은 시간이 소요된다.
  • 프로세스 컨텍스트 스위칭의 비효율성, 오버헤드가 크다.
  • 프로세스 사이에 통신이 어렵다. (IPC,LPC,공유 메모리로 통신을 해야만하므로 비용이 비싸다.)

스레드: 다른 스레드와 공간과 자원을 공유하면서 사용

  • 스레드는 프로세스 내부에서 작업을 처리하는 주체
  • 스레드는 자원 중에 stack 만 따로 할당 받고 나머지 영역은 스레드끼리 서로 공유함

스레드를 사용함으로써 해결한 문제들

  • 프로세스보다 작은 실행 단위 구현
  • 프로세스의 생성,소멸에 따른 오버헤드 감소 => 프로세스 생성,삭제 보다 스레드 생성,삭제가 오버헤드가 적음
  • 스레드간 자원을 공유함으로써 빠른 컨텍스트 스위칭(code,data,heap)
  • 프로세스들의 통신 시간,방법,어려움 해소

프로세스 vs 스레드

  • 운영체제(OS)는 프로세스마다 독립된 메모리 영역을 code/data/stack/heap의 형식으로 할당한ㅁ다.

    • 각각 독립된 메모리 영역을 할당하기에 프로세스는 다른 프로세스의 변수나 자료에 접근할 수 없다.
  • 프로세스 내의 스레드는 메모리를 서로 공유할 수 있다.

    • 프로세스는 할당받은 메모리 영역 내의 Stack 형식으로 할당된 메모리 영역은 따로 할당받고, code/data/heap 형식으로 할당된 메모리 영역을 공유한다.
    • 각각의 스레드는 별도의 stack 메모리를 가지나 heap 메모리 등의 메모리는 서로 읽고 쓸수 있게 된다.

프로세스의 사전적 정의

  • 컴퓨터에서 연속적으로 실행하고 있는 컴퓨터 프로그램
  • 메모리에 올라와 실행되고 있는 프로그램의 인스턴스(독립적인 개체)
  • 운영체제로부터 시스템 자원을 할당받는 자원의 단위
  • 정리하면 프로그램의 실행된 부분을 의미합니다.

스레드의 사전적 정의

  • 프로세스 내에서 실행되는 여러 흐름의 단위
  • 프로세스의 특정한 수행 경로
  • 프로세스가 할당받은 자원을 이용하는 최소 실행 단위

프로세스와 스레드의 주소 공간

프로세스의 주소 공간

  • 각각 독립된 메모리 영역(Code, Data, Stack, Heap)을 할당받습니다.
    • 코드 영역(code area): 프로그래머가 작성한 프로그램이 저장되는 영역
    • 데이터 영역(data area): 코드가 실행되면서 사용한 환경이나 파일들의 각종 데이터들이 모여있습니다.
    • 스택 영역(stack area): 호출한 함수가 종료되면 되돌아올 메모리의 주소나 지역 변수 등이 저장됩니다.
    • 힙 영역(heap area): 동적으로 할당되는 데이터를 위해 존재합니다
  • 최소 1개 이상의 스레드(메인 스레드)를 가지고 있다.
  • 각 프로세스는 별도의 주소 공간에서 실행되며 기본적으로 다른 프로세스의 자원에 접근할 수 없다.
  • 한 프로세스가 다른 프로세스의 자원에 접근하려면 프로세스 간 통신(IPC)를 사용해야 한다.
    • ex. 파이프, 파일, 소켓 등을 이용한 통신 방법
  • 그림에서 여러 프로세스가 동시에 실행되고 관리 되는 것 처럼 보인다. 하지만 CPU는 한 번에 한 가지 명령밖에 처리할 수 없다. 즉, 동시가 아니라 빠르게 프로세스들을 번갈아가면서 실행하고 관리하고 있는 것이다.

스레드의 주소 공간

스레드의 특징

  • 프로세스 내에서 각 필요한 Stack만 할당받고 Code, Data, Heap 영역은 공유해서 각 스레드가 공유합니다.
  • 같은 프로세스 내 스레드끼리 자원(Heap 등)을 공유하며 실행됩니다.
    • 즉, 스레드는 공유하는 자원인 Heap 영역에 있는 변수를 수정할 수 있습니다.
  • 프로세스 하나만을 사용해서 프로그램을 실행하기에는 메모리의 낭비가 발생합니다.
    • 스레드는 프로세스와 다르게 스레드 간 메모리를 공유하며 작동합니다.
    • 즉, 프로세스가 할당받은 자원을 이용하는 처리 작업(실행의 흐름)의 단위 입니다.

  • 스레드가 독립적으로 가지고 있는 부분 = 작업 흐름과 관련됨
    • program counter (실행할 명령어)
    • register set
    • stack space
  • 스레드가 동료 스레드와 공유하는 부분 = 작업 데이터와 관련됨
    • code section
    • data section
    • OS resources

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

멀티프로세스

  • 두개 이상 다수의 프로세서(CPU)가 협력적으로 하나 이상의 작업(Task)을 동시에 처리하는 것이다. (병렬처리)
  • 각 프로세스 간 메모리 구분이 필요하거나 독립된 주소 공간을 가져야 할 경우 사용한다.
    장점
  • 독립된 구조로 안전성이 높은 장점이 있다.
  • 프로세스 중 하나에 문제가 생겨도 다른 프로세스에 영향을 주지 않아, 작업속도가 느려지는 손해정도는 생기지만 정지되거나 하는 문제는 발생하지 않는다.
  • 여러개의 프로세스가 처리되어야 할 때 동일한 데이터를 사용하고, 이러한 데이터를 하나의 디스크에 두고 모든 프로세서(CPU)가 이를 공유하면 비용적으로 저렴하다
    문제점
  • 독립된 메모리 영역이기 때문에 작업량이 많을수록( Context Switching이 자주 일어나서 주소 공간의 공유가 잦을 경우) 오버헤드가 발생하여 성능저하가 발생 할 수 있다.
  • Context Switching 과정에서 캐시 메모리 초기화 등 무거운 작업이 진행되고 시간이 소모되는 등 오버헤드가 발생한다.

멀티스레드

하나의 프로세스에 여러 스레드로 자원을 공유하며 작업을 나누어 수행하는 것
장점

  • 시스템 자원소모 감소 (자원의 효율성 증대)
    • 프로세스를 생성하여 자원을 할당하는 시스템 콜이 줄어 자원을 효율적으로 관리할 수 있다.
  • 시스템 처리율 향상 (처리비용 감소)
    • 스레드 간 데이터를 주고 받는 것이 간단해지고 시스템 자원 소모가 줄어든다.
    • 스레드 사이 작업량이 작아 Context Switching이 빠르다. (캐시 메모리를 비울 필요가 없다.)
  • 간단한 통신 방법으로 프로그램 응답시간 단축
    • 스레드는 프로세스 내 스택영역을 제외한 메모리 영역을 공유하기에 통신 비용이 적다.
    • 힙 영역을 공유하므로 데이터를 주고 받을 수 있다.

스레드 풀


프로그램이 작업을 동시에 실행할 수 있도록 여러 스레드를 미리 생성해두고 유지 관리합니다.
여러 스레드를 동시에 만들어 실행(병렬 처리)할 수 있다.

  • 스레드 풀은 컴퓨터 프로그램에서 실행의 동시성을 달성하기 위한 소프트웨어 디자인 패턴이다.
  • 쓰레드 풀은 작업 처리에 사용되는 스레드를 제한된 개수만큼 정해 놓고 작업 큐(Queue)에 들어오는 작업들을 하나씩 스레드가 맡아 처리하는 것을 말합니다.
    • 해야할 일을 순서대로(작업 큐) 스레드들에게 할당 해주며 처리하도록 합니다.

스레드 풀의 동작
1. 초기화: 쓰레드 풀을 사용하기 전에 초기화해야 합니다. 이 단계에서는 쓰레드 풀의 크기, 최대 쓰레드 수, 작업 큐 등의 매개변수를 설정합니다.
2. 작업 수신: 쓰레드 풀은 작업을 수신하고 처리할 준비를 합니다. 작업은 일반적으로 작업 큐에 추가됩니다.
3. 작업 수행: 쓰레드 풀에서는 미리 생성된 쓰레드들이 작업 큐를 모니터링하고 대기 중인 작업을 가져와 처리합니다. 이때 쓰레드 풀 내의 쓰레드들은 일반적으로 무한 루프를 돌면서 작업을 가져오기 위해 대기합니다.
4. 작업 처리: 쓰레드 풀의 스레드가 작업을 가져와서 처리합니다. 작업은 일반적으로 작업 큐에서 FIFO(선입선출) 방식으로 가져오게 됩니다.
5. 작업 완료 및 반환: 작업이 완료되면 해당 결과를 반환하고, 쓰레드는 다시 작업 큐에서 새로운 작업을 가져오기 위해 대기 상태로 돌아갑니다.
6. 작업 대기: 작업 큐에 새로운 작업이 추가되면 쓰레드 풀의 스레드들은 대기 상태를 벗어나 작업을 가져와 처리합니다. 이를 반복하여 계속적으로 작업을 수행합니다.
7. 종료: 쓰레드 풀을 더 이상 사용하지 않을 때 종료합니다. 종료할 때는 모든 작업이 완료되었는지 확인하고, 필요에 따라 남은 작업들을 처리하거나 버릴 수 있습니다

스레드 풀을 사용하는 이유

  1. 프로그램의 성능 저하를 방지하기 위함
    • 매번 발생하는 작업을 병렬처리하기 위해 쓰레드를 생성/수거하는 데 따른 부담은 프로그램 전체적인 퍼포먼스를 저하시킨다. 따라서 쓰레드풀을 만들어 놓고 사용합니다.
    • 쓰레드 또한 프로세스가 할당한 메모리를 사용합니다.
    • 즉, Java의 경우 쓰레드를 생성하면 JVM 메모리를 소비하게 되는 것이다. 쓰레드 자체도 레지스터와 스택을 가지고, 쓰레드도 컨텍스트 스위칭이 일어나기 때문에 쓰레드 생성에 따른 메모리 할당을 무시할 수 없습니다.
  2. 다수의 사용자 요청을 처리하기 위해
    • 대규모 프로젝트에서 특히 중요합니다.
    • 다수의 사용자의 요청을 수용하고, 빠르게 처리하고 대응하기 위해 쓰레드풀을 사용합니다.
    • 특히 병목 현상이 발생하는 I/O 작업과 데이터베이스 작업에서 주로 사용됩니다.
    • 쓰레드가 아무리 빠르게 생성되더라도 시스템 스케줄러에서 쓰레드의 우선순위를 매번 할당해야 하는데, 쓰레드풀을 이용하면 일정 쓰레드가 이미 생성되기 때문에 쓰레드풀에 의해 라이프 사이클이 관리되고, 쓰레드 풀에 의해 작업이 큐를 이용하게 되어 우선순위가 배분되고 처리됩니다.

스레드풀의 장단점

장점

  • 쓰레드를 생성/수거하는데 비용이 들지 않습니다.
  • 쓰레드가 생성될 때 OS가 메모리 공간을 확보해주고 메모리를 쓰레드에게 할당해줍니다.
  • 쓰레드 풀을 미리 만들어 두기 때문에 처음에 생성하는 비용은 들지만 이전의 쓰레드를 재사용할 수 있으므로 시스템 자원을 줄일 수 있고, 작업을 요청 시 이미 쓰레드가 대기 중인 상태이기 때문에 작업을 실행하는 데 딜레이가 발생하지 않습니다.

단점

  • thread pool에 thread를 너무 많이 생성해 두었다가 사용하지 않으면 메모리 낭비가 발생합니다.
  • Thread pool의 단점 개선 : Fork Join Thread Pool

    큰 업무를 작은 업부로 나누어 배분하여 일을 한 후, 일을 취합하는 형태

동시성과 병렬성

동시성

싱글 코어에서 멀티 스레드를 동작시키기 위한 방식으로 멀티 태스킹을 위해 여러 개의 스레드가 번갈아가면서 실행되는 성질을 말합니다. 동시성을 이용한 싱글 코어의 멀티 태스킹은 각 스레드들이 병렬적으로 실행되는 것처럼 보이지만 사실은 번갈아가면서 조금씩 실행되고 있는 것입니다.

병렬성

멀티 코어에서 멀티 스레드를 동작시키는 방식으로, 한 개 이상의 스레드를 포함하는 각 코어들이 동시에 실행되는 성질을 말합니다. 병렬성은 데이터 병렬성(Data parallelism)과 작업 병렬성(Task parallelism)으로 구분됩니다.

  • 데이터 병렬성

데이터 병렬성은 전체 데이터를 쪼개 서브 데이터들로 만든 뒤, 서브 데이터들을 병렬 처리하여 작업을 빠르게 수행하는 것을 말합니다.

자바8에서 지원하는 병렬 스트림이 데이터 병렬성을 구현한 것입니다.

서브 데이터는 멀티 코어의 수만큼 쪼개어 각각의 데이터들을 분리된 스레드에서 병렬 처리합니다.

  • 작업 병렬성

작업 병렬성은 서로 다른 작업을 병렬 처리하는 것을 말합니다.

대표적인 예는 웹 서버로, 각각의 브라우저에서 요청한 내용을 개별 스레드에서 병렬로 처리합니다.

profile
ㅇㅇ

0개의 댓글