[운영체제/OS] 멀티 스레딩 - 기본
스레드의 등장
- 스레드는 컴퓨팅의 병렬적 수행이 필요했기 때문에 등장했다.
- 행렬 곱과 같은 매우 많은 양의 연산을 하는 목적의 프로세스를 빠르게 수행하기 위해 계산 부분을 나눠 병렬적으로 처리하면 쉬운 것처럼...
- 과거에는 그러한 것들을 위해 프로세스를 여러개 만들어서 수행해보고자 했다.
- 하지만 프로세스는 그 자체로 굉장히 무거운(비싼) 개념이다.
- 따라서 프로세스의 하위 개념인 스레드가 등장하였다.
프로세스의 역할
자원 관리자로서의 역할
- 프로세스는 자원의 주인이다. 가상 메모리 공간을 할당 받아 해당 프로세스를 위해 확보하고 있는다.
- I/O 디바이스, 파일 등 자원을 관리한다.
수행자로서의 역할
- 프로세스가 수행할 명령어를 수행하는 역할도 존재한다.
- 명령어를 수행하는 주체는 프로세스에 종속되어 명령어를 수행한다.
이처럼 프로세스는 크게 두 가지의 역할로 이루어진 주체인데, 수행자의 역할을 맡는 스레드라는 개념을 만든 것이다.
스레드의 특징
- 상태가 존재한다. (running, ready, stopped)
- 프로세스의 자원에 접근 가능하다.
- 하나의 스레드는 하나의 함수에 할당되어 동작하기 때문에 런타임 스택(지역 변수를 위한)이 존재한다.
- 스레드는 스케쥴링의 대상이기 때문에 그와 관련된 정보를 담을 TCB를 가진다.
위 사진처럼 기존의 프로세스(싱글 스레딩)는 하나의 스택을 가졌지만 오른쪽의 멀티 스레딩 프로세스는 여러개의 스레드를 가진다. 그리고 각 스레드는 스택과 TCB를 가지게 된다.
멀티 스레딩의 이점
- 효과적인 병렬 컴퓨팅. 기존 목표였다.
- 자원 공유. 스레드는 같은 프로세스 내에 존재하는 스레드라면 자원을 공유할 수 있기 때문에, 자원 공유가 쉬워졌다.
- 경량 프로세스이기에 생성과 소멸에 드는 비용이 매우 적다.
- 반응속도(사용자 경험) 증가.
- 만약 하나의 프로세스가 하나의 스레드로만 동작한다면, 다음과 같은 일이 발생한다.
- 웹 브라우저를 켜서 youtube.com에 접속하면 youtube.com의 데이터를 모두 받아오고 그것을 하나씩 렌더링 한다.
- 하지만 스레드가 여러개라면 데이터를 받아오는 스레드와 렌더링 스레드가 여러개여서 더 빠른 시간 내에 response를 받을 수 있게 된다. (사용자 경험의 증가)
위 다이어그램은 서버 애플리케이션의 동작 과정을 커널 계층과 유저 계층에 나누어 표현한 그림이다.
- 외부에서 네트워크 연결이 유저 애플리케이션에 도달한다.
- 연결만을 dispatch하는 스레드가 존재하여 그것을 관리한다.
- 연결의 세부사항을 기준으로 특정 로직을 수행하는 worker 스레드가 존재하여 그것을 수행한다.
만약 위 과정을 하나의 스레드가 수행한다면 한 번에 하나의 요청밖에 다루지 못하는 것 뿐 아니라 dispatch와 working 과정을 모두 수행하기 때문에 response time이 매우 길것이다.
하지만, 멀티 스레드 환경에서는 위와 같은 시나리오가 매우 짧은 response time 안에 해결될 것이다.
POSIX 스레드 모델
다음은 POSIX에서 제안한 스레드 API 모델이며 실제로 다양한 운영체제 이것을 지원한다.
Pthreads API | 설명 |
pthread_create() | 새 스레드를 생성한다. |
pthread_exit() | 명시된 스레드를 종료한다. |
pthread_join() | 명시된 스레드가 종료될 때까지 대기한다. |
pthread_yield() | CPU 사용을 멈춘다. (Ready Queue에서 빠져나오고 다시 삽입된다) |
관련 내용은 아래 링크에서 확인하자.
https://www.joinc.co.kr/w/Site/Thread/Beginning/PthreadApiReference
Pthread API 레퍼런스
Pthread API 레퍼런스 주의
www.joinc.co.kr
스레드 구현 방식
유저 레벨 스레드
- 스레드를 유저 레벨에서 구현하는 방법. 운영체제가 스레드를 지원하지 않아도 가상 스레드를 생성할 수 있는 방법.
- 하지만, 운영체제가 지원하지 않기 때문에 운영체제는 여러 스레드를 하나의 프로세스로 본다.
- 그렇기 때문에, 하나의 스레드가 Block을 요청하면 해당 프로세스 전체가 Block된다.
커널 레벨 스레드
- 운영체제가 지원해야만 사용할 수 있는 스레드 구현 방식
- 일반적인 방식이다.