Process Scheduling에 대해 스터디하던 중 Thread Scheduling 질문에 대한 답을 하지 못해 이번 기회에 정리하려고 한다!
우선 Thread Scheduling에 대해 이해하려면 다음 두개의 차이점을 알아야 한다.
- User Level Thread
- Kernel Level Thread
User Level Thread
- 프로세스 내의 Thread 관련 Library가 Thread를 관리한다.
- User Level Thread의 존재를 Kernel에서는 알지 못한다.
- 모든 관리에 커널이 관여하지 않기 때문에 가볍게 쓰레딩을 할 수 있다.
- 하나의 Thread라도 동작을 멈출 경우, 그 프로세스 전체가 Block된다.
- 멀티 프로세서를 전혀 이용할 수 없다.
ex. new Thread() 같이 프로세스 내에서 Thread를 생성하는 것
장점
- 스케줄링이나 동기화를 위해 커널을 호출하지 않기 때문에 인터럽트 발생 시 오버헤드가 적다.
- 커널은 사용자 스레드의 존재를 모르기 때문에 모드 전환이 없다.
단점
- 시스템 전반에 걸친 스케줄링 우선순위를 지원하지 않는다. (무슨 스레드가 먼저 동작할 지 모름. -> Thread 생성 시 우선순위를 정할 순 있지만 정확하지 않다.)
- I/O 작업 등에 의해 하나라도 Block된다면 전체 스레드가 Block된다.
Kernel Level Thread
- 스케줄링하는 주체가 커널이다.
- 커널이 모든 프로세스와 스레드를 관리하는 것을 의미한다.
- Thread Table이 커널에 합쳐져 하나만 존재한다.
- 각 프로세서에서 다른 두 개의 쓰레드를 실행할 수 있다.
장점
- 프로세스의 스레드들을 프로세서에 한번에 디스패치 할 수 있기 때문에 멀티프로세서 환경에서 매우 빠르게 동작한다.
- 커널이 직접 스레드를 제공해 주기 때문에 안정성과 다양한 기능이 제공된다.
단점
- 스케줄링과 동기화를 위해 커널을 호출하는데 무겁고 오래걸린다.
- 사용자 모드에서 커널 모드로의 전환이 빈번하게 이뤄져 성능 저하가 발생한다.
구조
- One-To-Many : 하나의 Kernel Thread가 여러 개의 Thread를 관리한다.
- One-To-One : 한 개의 Kernel Thread가 한 개의 Thread를 관리한다.
- Many-To-Many : 여러 개의 Kernel Thread가 여러 개의 Thread를 관리한다.
One-To-One의 경우 1CPU에서 하나의 쓰레드가 어떤 이유로 Block되어도 다른 쓰레드를 사용할 수 있다. 그러나 Kenel Thread가 생성되어야 하므로 오버헤드가 크다.
-> 유닉스, 리눅스 등이 해당 모델을 사용한다.
보통 Many-To-Many와 One-To-One을 섞은 모델을 사용하여 필요에 따라 유연하게 행동한다.

Light Weight Process(LWP)
- LWP란 User Thread가 CPU 리소스에 접근하기 위해 인터페이스 역할을 하는 사용자 공간의 Thread이다.
- Thread Library는 LWP에서 실행할 프로세스의 스레드와 기간을 등록한다.
- 응용 프로그램에서 LWP의 수는 User Thread의 수와 같다.
그럼 이제 본론인 Thread Scheduling에 대해 알아보도록 하자
Thread Scheduling
Thread Scheduling을 위해서는 스케줄링 정책과 우선 순위를 지정하는 것 외에 다른 작업을 추가적으로 해야한다.
User Level Thread Scheduling : 경합 범위 및 할당 도메인
1. Contention Scope (경합 범위)
Process Contention Scope (PCS)
- 경쟁 대상이 같은 프로세스에 있는 Thread이다.
- LWP에 접근하기 위해 경합한다.
- 우선 순위는 개발자가 해당 스레드를 생성할 때 정할 수 있다.
System Contention Scope(SCS)
- 시스템에 존재하는 모든 Thread끼리 경쟁한다.
- 스레드 라이브러리에 의해 각 LWP에 연결되고 시스템 스케줄러에 의해 커널 리소스에 엑세스하도록 예약된다.
- 리눅스, 유닉스 운영체제의 POSIX PThread 라이브러리는 스레드 생성 시 스레드의 경합 범위를 지정하는 Pthread_attr_setscope 함수를 제공한다.
결론적으로 스케줄링을 하는 방식 차이라고 생각된다. 스케줄링을 운영체제에 의해서 할지, 개발자가 임의로 정할지 그리고 경쟁 대상의 범위
PCS와 SCS의 병합
시스템 스케줄러가 CPU의 50% 자원을 P1에 할당했다고 가정한 상황을 가정하도록 하자.
남은 50% 중 25%는 PCS를 위한 공간이고, 25%는 SCS를 위한 자원이다. PCS Thread가 Thread Library를 통한 우선순위에 의해 25% 자원을 할당받을 것이고, SCS Thread는 시스템 스케줄러를 통한 우선순위에 의해 25%를 나눈 뒤 LWP, KLT를 통해 커널에 접근할 것이다. 이때 SCS 예약은 시스템 스케줄러를 통해 이루어 진다 (당연한 이야기)
장단점
- PSC의 경우 컨텍스트 전환, 동기화, 스케줄링 모든 것이 사용자 공간 내에서 이루어지므로 시스템 호출이 줄어들고 성능이 향상된다.
- PCS 스레드는 하나 이상의 사용 가능한 LWP를 공유한다. 반면 SCS는 모든 SCS 스레드에 대해 별도의 LWP가 연결된다. 모든 시스템 호출에 대해 별도의 KLT가 생성된다.
- 생성된 KLT 및 LWP 수는 생성된 SCS 스레드 수에 따라 크게 달라진다.
이는 스케줄링 및 동기화 처리의 커널 복잡성을 증가시킨다.
따라서 SCS 스레드 생성이 제한된다. 즉, SCS 스레드 수가 PCS 스레드 수보다 작아야 한다.