강의 메모 - 사용자 수준 스레드 & 커널 수준 스레드 #
개요 #
- 스레드는 사용자 수준 스레드(User Level Thread), 커널 수준 스레드(Kernel Level Thread) 로 구분된다.
- 사용자 수준 스레드 : 사용자 프로그램에서 관리하는 스레드
- 커널 수준 스레드 : OS에서 관리하는 스레드
** CPU의 할당 단위는 쓰레드다. **
사용자 수준 스레드(User Level Thread) #
- 스레드 라이브러리(Pthreads, WIndows Threads, Java Threads(JVM))에 의해 스레드의 생성, 종료, 스레드간 메시지 전달, 스케줄링 스레드 보관 등 모든 것을 관리한다.
- 커널은 사용자 수준 스레드에 대해 알지 못하며 단일 스레드 프로세스인 것처럼 관리한다.
- 커널은 프로세스 안에 스레드가 1개정도 있구나~ 하고 인식하는 정도로 안다.
- 커널의 간섭을 받지 않는다.
커널 수준 스레드(Kernel Level Thread) #
- 커널이 스레드와 관련된 모든 작업을 관리한다. (PCB, TCB 관리/유지)
- 커널은 커널 스레드의 모든 정보를 알고있으며, 커널 스레드는 OS 스케줄러에 의해 스케줄링 된다.
- CPU는 커널에 의해 생성된 커널 스레드의 실행만을 담당한다.
사용자 영역의 프로세스에서는 쓰레드를 생성하는데(JAVA 등) 이 쓰레드들은 커널의 쓰레드와 아무 관련이 없다. CPU는 커널 쓰레드만 인식하는데, 어떻게 우리가 만든 쓰레드를 인식해서 CPU가 동작할까? 라는 의문이 생긴다.
멀티스레딩 모델 #
- CPU는 OS Scheduler가 예약하는 커널 스레드만 할당받아 실행시키기 때문에 사용자 수준 스레드는 커널 수준 스레드와의 매핑이 필요하다.
- 사용자 수준 스레드는 3가지 모델로 커널 수준 스레드와 매핑하여 구현할 수 있다.
- 다대일 스레드 매핑
- 일대일 스레드 매핑
- 다대다 스레드 매핑
다대일 스레드 매핑 (many to one thread mapping) #
다수의 사용자 수준 스레드가 커널 수준 스레드 1개에 매핑하는 유형으로 사용자 수준의 스레드 모델이라고 볼 수 있다.
- Kernel 수준 쓰레드는 사용자 수준 스레드를 아예 알지 못한다.
- User Space, Kernel Space는 매핑 되어도 서로 알지 못한다는 것이다.
- CPU는 Kernel 쓰레드만 인식한다.
- 커널 개입 없이 사용자 스레드끼리의 스위칭이 발생하므로 오버헤드가 적다.
- 스케쥴링과 동기화를 하려고 커널을 호출하지 않으므로 커널 영역으로 전환하는 오버헤드가 줄어든다.
- 개별 스레드 단위가 아닌 단일 스레드의 프로세스 단위로 프로세서를 할당하기 때문에 멀티코어를 활용한 병렬처리를 할 수 없다.
- 커널 수준 쓰레드는 사용자 수준 쓰레드를 모르므로, 커널 영역은 프로세스 안에서 하나의 쓰레드가 있다고 일단 인식하는 구조다.
- 만약 CPU는 4개인데, 커널 영역 쓰레드는 2개이면, 나머지 2개의 CPU는 놀게된다. 유저 쓰레드는 여러개임에도 불구하고 놀게되는 단점이 있다. (병렬처리를 할 수 있음에도 불가능)
- 한 쓰레드가 Block I/O가 발생하면 모든 스레드들이 Block이 발생하는데 이는 프로세스 자체를 블록하기 때문이다.
- 1개의 쓰레드가 I/O Block이 되면 나머지 2개는 사용이 가능해야하는데, Kernel 수준 쓰레드 영역에서는 프로세스만 인지하므로, 이 프로세스 내에 Block된 스레드가 있다면 전체 프로세스가 Block 되버린다. 쓰레드가 1개밖에 없는 것처럼 인식하므로 1개가 Block되면 프로세스 전체가 Block되는 단점이 있다.
- 자바에서 초기 버전의 Green Thread가 이 모델에 해당한다고 볼 수 있다.
일대일 스레드 매핑 (one to one thread mapping) #
사용자 수준 스레드와 커널 수준 스레드가 1:1로 매핑된다. 커널 수준의 스레드 모델이다.
- 커널이 전체 프로세스와 스레드 정보를 유지해야하기 때문에 컨텍스트 스위칭 시 사용자 모드에서 커널 모드로 전환해서 스케줄링 하는 등의 오버헤드가 발생
- 자원 한정으로 인해 스레드를 무한정 생성할 수 없다. 대안으로 스레드 풀을 활용한다.
- 이게 단점이다.
- 스레드 단위로 CPU를 할당하기 때문에 멀티 코어를 활용한 병렬 처리가 가능하다.
- CPU가 6개일때 하나씩 할당되므로 병렬 처리가 가능하다.
- 스레드 중 한개가 대기상태가 되더라도 다른 스레드를 실행할 수 있다. 즉, 멀티스레드의 동시성을 활용할 수 있다.
- 쓰레드 1개가 Block 되더라도 나머지는 CPU 할당받고 실행될 수가 있다.
- 자바에서 Native Thread가 이 모델에 해당한다고 볼 수 있다.
다대다 스레드 매핑 (many to many thread mapping) #
- 여러개의 사용자 수준 스레드를 같은 수 또는 그보다 작은 수의 커널 수준 스레드로 매핑하는 유형이다.
- 각 커널 수준의 스레드가 사용자 수준의 스레드 1개 이상과 매핑된다.
- 다대일, 일대일 모델의 단점을 어느정도 해결한다.
- 개발자는 필요한 만큼 많은 사용자 수준 스레드를 생성할 수 있고, 커널 수준 스레드가 멀티 프로세서에서 병렬로 수행될 수 있다.
- 사용자 수준 스레드가 I/O 시스템 콜을 발생시켰을 떄, 커널이 다른 스레드의 수행을 스케줄 할 수 있다.
- User 수준 쓰레드 1개가 Block 되더라도, 다른 User 수준 쓰레드와 커널 수준 쓰레드가 매핑될 수 있다.