JJ BLOG

Ruby on Rails로 웹개발을 하고있는 웹개발자입니다.

쓰레드(Thread)

25 Oct 2019 »

쓰레드(Thread)란?

쓰레드는 CPU를 구성하는 기본단위입니다. Thread ID, Program counter, register set 그리고 stack으로 구성되어 있습니다. 작업이 겹치는 프로세스를 여러 개 생성하는 것은 메모리의 낭비입니다. 그래서 프로세스는 하나만 생성하고 PC(Program Counter)만 여러개 생성합니다. 즉 CPU 수행 단위를 여러 개 두는 것입니다. 이를 쓰레드라고 합니다.

process_and_thread

각각 다른 작업을 수행하려면 앞의 포스팅에서 말씀드린 것처럼 PC 값이 꼭 필요합니다. 또 메모리에 어떤 레지스터 값들을 세팅해야합니다. 때문에 쓰레드마다 PC 값과 레지스터 값들이 들어가는 것입니다.


쓰레드를 이용해 프로세스를 수행했을 때의 장점


1. 빠른 반응

쓰레드를 이용하면 하나의 서버쓰레드가 blocked 상태인 동안에도 동일한 프로세스의 다른 쓰레드가 실행되어 보다 빠르게 처리가 가능합니다. 예를들어 웹 브라우저가 웹 페이지를 읽어올 때 작업이 오래 걸리는 경우 웹 브라우저 상태는 blocked 상태가 됩니다. 하지만 다른 쓰레드들은 읽어온 데이터를 화면에 뿌려주는 역할을 할 수 있어 보다 사용자에게 빠르게 웹 페이지가 보여지게 됩니다.

2. 자원의 공유

쓰레드들은 서로 자원을 공유합니다. 쓰레드의 자원 공유에 대해 이야기 하기에 앞서 앞에서 설명을 못드린 프로세스의 자원 공유 방법에 대해 이야기해보겠습니다. 프로세스 간에도 자원을 공유합니다.

Shared Memory
상호 작용하는 프로세스 사이에 하나의 저장 공간을 만들어 정보를 공유합니다. 이는 프로세스끼리 동시에 메모리에 접근을 하게 되면 충돌(동시에 값을 수정) 하여 데이터의 불일치를 초래합니다.

Message Passing
Message Passing은 상호 작용하는 프로세스 간 작업이 필요한 경우 운영체제에게 각자의 Message를 전달함으로써 통신합니다. 이 방식은 운영체제를 거쳐야 하기 때문에 Shared Memory에 비해 속도가 느립니다.

프로세스의 자원 공유 방법에 대해서 알아봤습니다. 이제 쓰레드에 대해 이야기해보겠습니다. 쓰레드는 앞에서 말했듯이 자원을 공유합니다. 때문에 프로세스와 같이 메모리 공간을 따로 만들 필요도, 운영체제를 거칠 필요도 없습니다. 이러한 특징은 Multi-Tread가 Multi-Process 보다 좋은 점이라고 할 수 있습니다.

  • 자원의 공유로 인해 문맥 교환의 시간과 Process에 메모리와 자원을 할당하는 것이 더욱 효율적으로 이루어집니다.

  • Multi-CPU에서 Multi-Thread 기법을 통해 확장성을 가질 수 있습니다.


Multi-Thread Models

Multi-Thread의 Model을 살펴보기 전에 User ThreadKernel Thread에 관해 이야기해보겠습니다. User Thread#include<thread> 혹은 import를 통해 쓰레드를 이용합니다. 커널의 지원 없이 사용자 공간에서 실행되므고 빠른 쓰레드 연산이 가능합니다.

Kernel Thread는 커널 내에 있는 쓰레드를 의미합니다. 운영체제가 직접 제공하고 관리하는 쓰레드입니다. 커널이 쓰레드를 인식하고 프로세스와 유사하게 스케줄링 합니다. 때문에 커널의 오버헤드가 더해져 쓰레드 생성과 스케줄링이 느릴 수 있습니다.

Multi-Thread Models에는 Many-to-One model, One-to-One model, Many-to-Many model, Two-Level model이 있습니다.

many_to_one_model

먼저 Many-to-One model로 하나의 Kernel Thread가 다수의 User Thread를 처리하는 구조입니다. 이러한 모델은 User Thread 모델이며 모든 쓰레드 제어가 사용자 수준의 라이브러리에서 지원됩니다. 이러한 구조는 User Thread를 처리하던 중 System Call에 의해 blocking이 된다면 전체 프로세스가 막히는 병목현상이 일어나는 문제점을 갖습니다.


one_to_one_model

다음으로 One-to-One model 입니다. 처리해야 할 User Thread 한 개당 Kernel Thread를 대응시켜 작업을 진행하는 구조입니다. 이러한 일대일 대응 구조는 Kernel Thread 생성에 과도한 생성의 문제를 가져오게 됩니다.


many_to_many_model

앞의 두 모델을 보완하여 합친 모델이 Many-to-Many model입니다. 다수의 User Thread를 다수의 Kernel Thread가 처리하는 구조입니다.


two_level_model

마지막으로 Many-to-Many model을 더욱 보완한 Two-level model 입니다. Many-to-Many model과 One-to-One model을 합친 구조로 중요한 작업은 One-to-One 구조를 통해 처리하고 나머지는 Many-to-Many 구조를 통해 처리합니다. 이렇게 하면 중요한 작업에서의 기다림 현상을 줄일 수 있습니다.