1. 스레드의 특징
- 프로세스는 프로그램의 단위이고, 실제로 상태변화를 하거나 컴퓨터에서 task로 사용하는 단위는 스레드이다.
- 스레드는 프로세스 내에서 실행되는 여러 흐름의 단위이다.
- CPU의 최소 작업 단위이며, CPU 코어에 따라 사용 가능한 갯수가 결정된다.
- 한 프로세스 내에 반드시 하나 이상의 스레드가 존재하며, 스레드가 여러개 존재하는 것을 멀티스레드라고 한다.
- 프로세스가 1번에 1개 작업만 수행 : 단일 스레드 (Single Thread)
- 프로세스가 1번에 n개 작업을 수행 : 다중 스레드 (Multi Thread)
- 각 스레드는 스레드 ID, 프로그램 카운터(PC), 레지스터 집합, 스택을 독립적으로 소유한다.
- 같은 프로세스 내에 스레드들은 서로 코드/데이터/힙 영역, open한 파일 등의 시스템 자원을 공유한다.
2. 스레드는 왜 필요한가?
과거에는 프로세스와 종속된 Sub 프로세스를 만들어 작업을 수행했다. 이것은 다중 코어 프로그래밍을 흉내내는 정도에 불구했고, 각 프로세스별 데이터 공유 방법 (공유 메모리, 메시지 패싱, 파이프)을 추가로 설계해야 하는 단점이 있었다. 또한, 프로세스 생성은 자원 참조 등 컨텍스트 스위칭이 일어나 성능 저하를 야기시켰다.
그래서 하나의 프로세스 내에서 여러 개의 실행 흐름(단일, 동시적, 병렬적)을 두어 작업을 효율적으로 처리하기 위한 모델을 만들 것이 스레드다.
이렇게 멀티 프로세스로 실행되는 작업을 멀티 스레드로 실행하게 되면 프로세스를 생성해 자원을 할당하는 과정도 줄어들 뿐더러 프로세스를 컨텍스트 스위칭하는 것보다 오버헤드를 더 줄일 수 있게 된다.
뿐만 아니라 프로세스간의 통신 비용보다 하나의 프로세스 내에서 여러 스레드간의 통신 비용이 훨씬 적으므로 작업들 간의 통신 부담을 줄일 수 있게 된다.
ex) 웹 브라우저
이미지/텍스트를 표시하는 스레드, 네트워크에서 데이터를 가져오는 스레드, 파일 다운로드 받는 스레드 등등
한 프로세스 내에서 여러개의 작업을 해야하는 경우가 생긴다.
3. 사용자 스레드와 커널 스레드
스레드를 지원하는 주체에 따라 사용자 스레드와 커널 스레드로 나뉜다.
1) 사용자 스레드 : 개발자가 만든 스레드
- 커널의 지원/인식 없이 커널 영역 위, 사용자 공간(User space)에서 동작하는 스레드이다.
- 사용자 레벨의 스레드 라이브러리를 통해 구현(제공)된다. (예. Pthread, Java 스레드)
- 동일한 메모리 영역에서 스레드가 생성 및 관리되므로 속도가 빠르다.
- 커널의 관여없이 스레드를 생성, 스케줄링, 관리한다.
- 스레드의 멈춤은 프로세스 자체의 blocking을 유발한다.
2) 커널 스레드 : OS가 만든 스레드
- 커널 영역(Kernel space)에서 동작하는 스레드이다.
- 커널이 스레드를 인식하고 프로세스와 유사하게 스케줄링한다.
- Windows, Linux, macOS 등 대부분의 운영체제가 지원하고 있다.
- 코어가 2개인 시스템이라면, 커널 스레드도 2개 있어야 두 개의 서로 다른 스레드를 병렬적으로(Simultaneously, Physically parallel) 수행할 수 있다.
즉, 듀얼코어 시스템에서 커널이 병렬적으로 돌아가기 위해선 2개의 커널 스레드가 반드시 필요하다.
3) 사용자 스레드와 커널 스레드의 관계
CPU 스케줄링은 커널 스레드를 통해 이루어진다. 스레드가 CPU 스케줄링의 단위가 되는데, 두개의 스레드중 커널 스레드가 CPU 스케줄링의 단위가 된다. 따라서, 각 커널 스레드는 CPU 스케줄링을 통해 병렬적으로 실행된다.
스케줄링은 프로세서를 누가 사용할 지 결정하는 것이다. 사용자 스레드가 프로세서를 할당받아 수행되기 위해서는, 커널 스레드와의 연결(매핑)이 이루어져야 한다. 즉, 사용자 스레드는 커널 스레드를 통해 프로세서를 사용할 수 있게 된다. 커널 스레드와 매핑되지 못한 사용자 스레드는 block 된다.