[운영체제] 스레드(Thread)

유니야·2023년 1월 4일

운영체제(OS)

목록 보기
4/5
post-thumbnail

✏️ Thread

OS가 CPU수행 시간을 할당하는 기본 단위. 또는 프로세스 내부 제어권의 흐름

💻 스레드의 구성

  • Thread ID
  • Program counter
  • Register set
  • Stack space

💻 싱글 스레드와 멀티 스레드

  • 싱글 스레드(Single thread)
    한 프로세스가 하나의 스레드를 이용해 한 번에 한 가지 작업만 수행하는 것.
  • 멀티 스레드(Multi thread)
    한 프로세스가 여러 스레드로 동시에 여러 작업을 수행하는 것.

💻 메모리 구조 관점에서 본 프로세스와 스레드

자식 프로세스가 생성되면 부모프로세스가 가진 핸들테이블을 제외한 모든 것(Code/Data/Heap/Stack영역)이 독립적으로 만들어진다. 이러한 메모리 구조를 지녔기 때문에 프로세스 간 데이터를 주고 받기 위해서는 IPC(Interprocess Communication)가 필요하다.
하지만 스레드의 경우에는 다르다. 프로세스가 스레드A와 B를 생성한 경우 스레드를 생성할 때마다 해당 스레드의 ThreadStack영역만이 독자적으로 생성되고, 나머지 영역은 부모 프로세스 영역을 공유하고 있다. 이와 같이 스레드는 공유하는 영역이 많기 때문에 프로세스에 비해 컨텍스트 스위칭이 빠르다.

  • 각 스레드가 독자적으로 가지고 있는 영역
    • 레지스터 상태, Stack
  • 스레드끼리 공유하는 영역
    • Code/Data/Heap 영역, 운영체제 자원

💻 스레드의 Context Switching

캐쉬는 CPU와 메인 메모리 사이에 위치하며, CPU에서 한 번 읽어들인 메모리의 데이터를 저장하고 있다가 CPU가 다시 그 메모리에 저장된 데이터를 요구할 때 메인 메모리를 통하지 않고 데이터를 전달해 주는 용도이다.
프로세스의 컨텍스트 스위칭이 일어났을 때, 프로세스 간 공유하는 데이터가 없기 때문에 캐쉬에 쌓아둔 데이터를 없애고 새로운 캐쉬 정보를 쌓아야 한다. 이것이 프로세스 컨텍스트 스위칭에 부담이 되는 요소이다.
반면 스레드는 자신의 생성한 부모 프로세스의 영역을 공유하고 있기 때문에 기존 캐쉬에 저장되어 있던 데이터가 유의미하다. 이것이 스레드의 컨텍스트 스위칭이 빠른 이유이다.

💻 스레드의 사용 이유

프로세스 내의 스레드는 모두 각각 독립적인 실행 파일이며, 프로세스의 일부이다. 프로세스를 여러 개 수행하지 않고 굳이 스레드를 사용하는 이유는 다음과 같다.

  • 프로세스를 생성하거나 Context Switching 하는 작업은 너무 무겁고 잦으면 성능 저하가 발생하는데, 스레드를 생성하거나 스위칭하는 것은 그에 비해 가볍다.
  • 두 프로세스가 하나의 데이터를 공유하려면 메시지 패싱 or 공유 메모리 or 파이프를 사용해야 하는데, 이는 효율이 떨어지며 구현 및 관리가 어렵다.

✏️ Multithreading

💻 멀티 스레딩을 하는 이유

  1. 병렬성(Parallelism)
  • 프로세서(CPU)가 여러 개인 경우, 멀티 스레드를 통해 병렬성을 높일 수 있다. 즉, 여러 작업이 동시에 수행될 수 있다.
  • 이는 프로세스의 스레드들이 각각 다른 프로세서에서 병렬적으로 수행될 수 있기 때문이다.
  • 병렬성은 CPU의 개수에 비례한다.
  1. 동시성(Concurrency)
  • 프로세서(CPU)가 하나인 경우, 멀티 스레드를 통해 동시성을 높일 수 있다.
  • 즉, 실제로는 각각의 시간에 한 작업만 수행되지만, 병렬적으로 수행되는 것처럼 보이게 하는 것이다.
  • 한 스레드가 blocked(waiting)되더라도 커널이 다른 스레드로 스위치시켜 실행할 수 있어 하나의 프로세서임에도 불구하고 빠른 처리가 가능하다.

💻 멀티 스레딩의 장점

  1. 응답성(Responsiveness)
    싱글 스레드는 작업이 끝나기 전까지 사용자에게 응답하지 않는다. 반면 멀티 스레드는 작업을 분리해서 수행하므로 실시간으로 사용자에게 응답할 수 있다.

  2. 자원 공유(Resource sharing)
    프로세스는 오직 공유 메모리나 메시지 패싱을 이용해 자원을 공유할 수 있다. 반면 스레드는 자신이 속한 프로세스 내의 스레드들과 메모리나 자원을 공유하여 효율적으로 사용할 수 있다.

  3. 경제성(Economy)
    프로세스 생성 비용 및 Context Switching 비용보다 스레드 생성 비용 및 Context Switching 비용이 저렴하다.

  4. 확장성(Scalability)
    싱글 스레드의 경우 한 프로세스는 오직 한 프로세서에서만 수행 가능하다. 반면 멀티 스레드의 경우 여러 프로세서에서 수행할 수 있으므로 훨씬 효율적이다.

✏️ 유저 스레드(User-level Thread)와 커널 스레드(Kernel-level Thread)

  • 유저 스레드(User-level Thread)
    • 커널 위에서 커널의 지원 없이 유저 수준의 스레드 라이브러리(Thread Library)가 관리하는 스레드.
    • 커널 스레드에 비해 안정성이 떨어지지만 커널 모드로 바꿔줄 필요가 없기 때문에 성능이 저하가 없다.
  • 커널 스레드(Kernel-level Thread)
    • 커널이 지원하는 스레드.
    • 유저 모드에서 커널 모드로 계속 바꿔줘야 하기 때문에 성능이 저하된다.

💻 유저 스레드와 커널 스레드의 연결 모델

  1. Many-to-One Model
    하나의 커널 스레드에 여러 유저 스레드를 연결하는 모델.
  2. One-to-One Model
    하나의 커널 스레드에 하나의 유저 스레드가 대응하는 모델.
  3. Many-to-Many Model
    여러 유저 스레드에 더 적거나 같은 수의 커널 스레드가 대응하는 모델.
  4. Two-level Model
    특정 유저 스레드를 위한 커널 스레드를 별도로 제공하는 모델. 점유율이 높아야 하는 유저 스레드를 더 빠르게 처리할 수 있다.

✏️ 스레드 풀(Thread Pools)

스레드를 요청할 때마다 매번 새로운 스레드를 생성, 수행, 삭제를 반복하면 성능이 저하된다. 따라서 미리 스레드 풀에 여러 스레드를 만들어두고 요청이 오면 스레드 풀에 존재하던 스레드를 할당해주는 방법을 사용한다. 이는 새로운 스레드를 만드는 것보다 효율적이고, 많은 양의 스레드를 일정한 크기의 풀 안에 묶어둘 수 있다는 장점이 있다.

0개의 댓글