쓰레드 (Thread)
쓰레드 정의
- 프로세스의 작업 흐름.
- CPU 코어에 따라 사용 가능한 갯수가 결정된다.
- 같은 프로세스 내 다른 쓰레드의 OS 자원들을 공유할 수 있다.
- 프로세스가 1번에 1개 작업만 수행 : 단일 쓰레드 (Single Thread)
- 프로세스가 1번에 n개 작업을 수행 : 다중 쓰레드 (Multi Thread)
쓰레드를 사용하는 이유
- 과거에는 프로세스와 종속된 Sub 프로세스를 만들어 작업을 수행하였다.
- 다중 코어 프로그래밍을 흉내내는 정도에 불구했다.
- 각 프로세스 별 데이터 공유 방법 (공유 메모리, 메시지 패싱, 파이프) 을 추가로 설계해야 하는 단점이 있었다.
- 또한 프로세스 생성은 자원 참조 등 문맥 교환 과정이 일어나 성능 저하를 야기한다.
- 쓰레드를 전환할 때에도 문맥 교환은 어쩔 수 없이 발생한다.
- 하지만 프로세스를 생성하는 것보다 비용이 적다.
쓰레드의 장점
- 응답성 : 사용자 인터페이스를 구성할 때 해당 영역에 대한 이벤트 처리 참조.
- 자원 공유 : 프로세스가 참조하는 자원의 메모리를 공유. 같은 공간에서 작업들을 진행.
- 규모 적응성 : 다중 프로세서 기반 시스템에 곧바로 적용할 수 있음.
- 경제성 : 문맥 교환이 발생하더라도, Sub 프로세스 생성 비용보단 적다.
다중 코어 프로그래밍
- CPU 코어가 단일에서 다중으로 증가하면서 생긴 패러다임.
- 단일 및 다중 코어를 사용하여 병행성 및 병렬성을 향상시키는 기법.
- 병행성 (Concurrency) : 1 회 실행에 단일 Thread 관여. 여러 태스크를 단위 시간으로 분할 및 번갈아가면서 실행.
- 병렬성 (Parallelism) : 1 회 실행에 다중 Thread 관여. 여러 태스크를 각 Thread 에게 할당 및 각각 동시에 실행.
- 동시성이든 병렬성이든 각 태스크 별 여러 개의 Thread 가 필요한 것은 사실이다.
- 병행성은 다중 코어를 사용하듯이 보여졌을 뿐. 코어가 늘어나면서 병렬성에 주목.
- 개발자는 아래와 같은 사항들을 추가로 고려해야 할 수도 있음.
- 태스크 독립, Thread 균형, 데이터 분리 및 종속성 최소화, 다중 스레드 기반 테스크 진행.
암달의 법칙 (Amdahl's Law)
- 병렬성 실행 구조로 이뤄진 응용 프로그램에 코어 개수를 적용 시켜 잠재적인 성능을 측정하기 위한 수치.
- 속도 <= 1 / (S + (1 - S) / N) (S : 병렬 작업 빈도, N : 코어 개수)
병렬 실행 기법
- 데이터 병렬 실행 : 태스크 별로 데이터를 부분 집합으로 나뉘어 실행.
- 태스크 병렬 실행 : 태스크를 각 Thread 들에게 할당 시켜 동시에 실행한다.
- 실제로는 데이터, 태스크 병렬 방식을 혼합 시켜 사용하는 것이 대표적이다.
사용자 / 커널 쓰레드
사용자 Thread
- 운영체제 사용자를 기반으로 한 Thread. (I/O 기능 등)
- POSIX, Pthreads, Win32 Threads, Java Thread API 등.
커널 Thread
커널 Thread 를 대놓고 사용하지 않는 이유
- 사용자 모드 -> 커널 모드로 바뀔 때 성능이 많이 저하된다.
- 사용자 Thread 를 사용해도 안정성만 떨어지지, 성능이 저하되는 건 아님.
다중 쓰레드 모델
다대일 (N:1) 모델
- 사용자 Thread 가 여러 개, 커널 Thread 가 1 개.
- 다중 Thread 작업이 어려울 수 밖에 없다.
- Blocking 시스템 콜 발생 시, 모든 프로세스들이 봉쇄 (Blocking) 된다.
- 커널 측에 하나의 사용자 Thread 만 접근할 수 밖에 없다.
일대일 (1:1) 모델
- 지금 시점에서 제공하는 운영체제들의 Thread 모델.
- 사용자 Thread 가 N 개, 커널 Thread 가 N 개.
- 연동은 커널 Thread 당 1 개의 사용자 Thread 로 진행.
- 다중 Thread 작업이 가능하다.
- 한 Thread 가 Blocking 시스템 콜 발생 시, 다른 Thread 가 대신할 수 있다.
- 사용자 Thread 를 생성할 때, 커널 Thread 를 생성해야 하는 문제 발생.
- 커널 Thread 가 많아지는 것은 시스템 성능에도 영향을 준다.
다대다 (M:N) 모델
- 멀티 플렉스 라고도 한다.
- 사용자 Thread 개수 > 커널 Thread 개수
- 커널 Thread 개수는 응용 프로그램 및 하드웨어 등에 따라 달라짐.
- 다중 Thread 작업이 가능하다.
- Blocking 시스템 콜 발생 시, 커널 측에서 Thread 스케쥴링을 진행.
- 두 수준 모델 (Two-Level Model) : 일대일, 다대다 모델의 융합.
- 특정 사용자 Thread 를 위한 커널 Thread 를 제공하는 모델.
- 점유율이 높은 사용자 Thread 에게 효율적이다.
- 실질적으로 CPU 코어 개수가 늘어나면서 커널 Thread 개수 제약을 두지 않고 있다.
쓰레드 풀
- 암묵적 쓰레딩 : 개발자는 병렬 작업에 대해서만 식별. 오로지 라이브러리 만이 Thread 를 관리한다.
- 다중 Thread 프로그래밍을 다룰 때 아래와 같은 문제점들을 해결한다.
- Thread 생성 비용 낭비
- Thread 개수 무한정 증가
- 프로세스를 시작할 때, 일정 개수의 Thread 를 생성. 요청 완료 시, 대기 큐에서 관리.
- Thread 재활용이 가능하고, 병렬 작업에 미비한 경우에 도움이 된다.
- 태스크 실행에 대한 차별성을 줄 수 있다.
멀티 쓰레딩 개발 시 확인 요소
- fork(), exec() 시스템 콜 관련
- 각 프로세스 별 복제 및 실행에 대한 문제를 유의할 것.
- 신호처리
- 동기적 신호 : 컴파일 오류 등
- 비동기적 신호 : 마우스 클릭, 키보드 입력 등
- 디폴트 처리기 (커널) 는 동기적 신호를, 사용자 정의 처리기 (사용자) 는 비동기적 신호를 담당한다.
- Thread 취소 (타깃 Thread)
- Thread 가 끝나기 전에 강제로 종료되는 과정.
- 비동기, 지연 취소 2 가지로 나뉨.
- Thread 로컬 저장 장치
- Thread 는 프로세스의 자원들을 공유할 수 있지만, 각 Thread 별로 차별성을 둘 때 사용한다.
- 스케쥴러 액티베이션
- 다대다 (M:N), 두 수준 모델 (Two-Level Model) 에 대한 문제.
- 경랑 프로세스 (LWP) 로 커널 및 사용자 Thread 를 연동한다.