쓰레드 (Thread)
프로세스가 생성되면 CPU 스케줄러는 프로세스가 해야 할 작업을 CPU에 전달하고 실제 작업은 CPU에서 진행된다. 이때 CPU 스케줄러가 CPU에 전달하는 실행 단위가 쓰레드이다. 즉, 쓰레드란 프로세스의 코드에 정의된 절차에 따라 CPU에 작업 요청을 하는 실행 단위이다. 운영체제 입장에서 작업 단위는 프로세스이고, CPU 입장에서 작업 단위는 쓰레드인 것이다.
CPU와 프로그래밍 기술이 발전함에 따라 멀티 코어를 지원하는 CPU가 생겨갔고 멀티쓰레드를 지원하기 시작했다. 현대의 운영체제는 프로세스를 다양한 쓰레드로 나누어 여러 개의 코어에 배분하여 시스템의 효율을 높인다.
잠깐 쓰레드와 관련된 용어를 살펴보도록 하겠다. 헷갈리지 않도록 잘 정리하도록 하자.
- 멀티쓰레드(Multi-Thread): 프로세스 내 작업을 여러 개의 쓰레드로 분할하여 작업의 부담을 줄이는 프로세스 운영 기법
- 멀티태스킹(Multi-Tasking): 운영체제가 CPU에게 작업을 줄 때 시간을 잘게 나누어 배분하는 기법으로, 시분할 시스템이라고도 한다.
- 멀티프로세싱(Multi-Processing): CPU를 여러 개 사용하여 여러 개의 쓰레드를 동시에 처리하는 작업 환경
- CPU 멀티쓰레드(CPU Multi-Thread): 한 번에 하나씩 처리해야 한느 쓰레드를 잘개 쪼개어 동시에 처리하는 명령어 병렬 처리 기법, 프로세스의 멀티쓰레드와 구분된다. 운영체제가 소프트웨어적으로 프로세스를 작은 단위의 쓰레드로 분할하여 운영하는 것은 멀티쓰레드이고 하나의 CPU가 여러 쓰레드를 동시에 처리하는 것은 CPU 멀티쓰레드이다.
멀티쓰레드 (Multi-Thread)
멀티쓰레드의 구조
fork() 시스템 호출을 통한 프로세스 생성은 코드 영역과 데이터 영역이 중복되어 존재한다는 단점이 있다. 쓰레드는 멀티태스킹의 낭비 요소를 제거하기 위해 사용된다. 비슷한 일을 하는 2개의 독립적인 프로세스를 만들지 않고 코드와 데이터를 공유하며 여러 개의 일을 하나의 프로세스 안에서 하는 것이다.
멀티쓰레드의 장단점
프로세스 내 공유가 가능한 부분을 제외하고 실행과 관련된 부분은 쓰레드로 나누어 관리하면 자원의 중복 사용을 피하고 낭비를 막을 수 있으며, 하나의 프로세스에서 여러 쓰레드를 사용하면 작업의 효율도 높일 수 있다. 멀티쓰레드의 장점은 다음과 같다.
- 응답성 향상: 한 쓰레드가 입출력으로 인해 작업이 진행되지 않아도 다른 쓰레드가 작업을 계속하여 사용자의 작업 요구에 빨리 응답할 수 있다.
- 자원 공유: 한 프로세스 내에서 독립적인 쓰레드를 생성하면 프로세스가 가진 자원을 모든 쓰레드가 공유하기에 작업을 원할하게 진행할 수 있다.
- 효율성 향상: 여러 개의 프로세스를 생성할 필요가 없어 불필요한 자원의 중복을 막아 시스템의 효율을 향상시킬 수 있다.
- 다중 CPU 지원: 2개 이상의 CPU를 가진 컴퓨터에서 멀티쓰레드를 사용하면 다중 CPU가 멀티쓰레드를 동시에 처리하여 CPU 사용량이 증가하고 프로세스의 처리 시간이 단축된다.
다만 멀티쓰레드에도 단점이 있는데, 바로 "모든 쓰레드가 자원을 공유하기에 한 쓰레드에 문제가 생길 경우. 전체 프로세스에 영향을 끼친다."는 것이다. 자원 공유는 멀티쓰레드의 장점이자 동시에 단점인 것이다.
멀티쓰레드 모델
프로세스가 커널 프로세스와 사용자 프로세스로 나뉘듯, 머쓰레드 또한 커널 쓰레드와 사용자 쓰레드로 나뉜다.
- 커널 쓰레드(Kernel-Level Thread): 커널이 직접 생성하고 관리하는 쓰레드
- 사용자 쓰레드(User-Level Thread): 라이브러리에 의해 구현된 일반적인 쓰레드로, 사용자 쓰레드가 커널 쓰레드를 사용하기 위해서는 시스템 호출을 거쳐야 한다.
커널 쓰레드와 사용자 쓰레드의 대응 방식은 다음으로 분류된다.
- 사용자 쓰레드(1 to N 모델): 사용자 쓰레드는 커널이 멀티쓰레드를 지원하지 않을 때 사용하는 방법으로, 사용자 레벨에서 라이브러리를 사용하여 쓰레드를 구현한다. 사용자 프로세스 내에 여러 개의 쓰레드가 존재하지만 커널의 쓰레드 하나와 연결되기에 1 to N 모델이다. 문맥 교환이 필요없다는 장점이 있으나, 여러 개의 쓰레드가 단 하나의 커널 쓰레드와 연결되어 있기에 커널 쓰레드가 대기 상태에 들어가면 모든 사용자 쓰레드도 같이 대기하게 된다. 또한 타임 슬라이스를 여러 쓰레드가 공유하기에 여러 개의 CPU를 동시에 사용할 수 없고 라이브러리에서 구현하기에 보안에 취약하다는 단점이 있다.
- 커널 쓰레드(1 to 1 모델): 커널 쓰레드는 커널이 멀티쓰레드를 지원하는 방식으로 하나의 사용자 쓰레드가 하나의 커널 쓰레드와 연결되기에 1 to 1 모델이다. 커널 쓰레드는 커널 레벨에서 모든 작업을 지원하기에 멀티 CPU를 사용할 수 있고 하나의 쓰레드가 대기 상태에 있어도 다른 쓰레드는 작업을 계속할 수 있다. 또한 커널의 기능을 사용하기에 보안에 강하고 안정적으로 작동한다. 다만, 문맥 교환을 할 때 오버헤드로 인해 느리게 작동한다.
- 멀티레벨 쓰레드(M to N 모델): 멀티레벨 쓰레드(하이브리드 쓰레드)는 사용자 쓰레드와 커널 쓰레드를 혼합한 방식으로, 커널 쓰레드의 개수가 사용자 쓰레드보다 같거나 적다. 멀티레벨 쓰레드는 사용자 쓰레드와 커널 쓰레드의 장단점을 모두 가진다. 하나의 커널 쓰레드가 대기 상태에 들어가도 다른 커널 쓰레드가 작업을 대신 하기에 유연한 작업이 가능하다. 그러나 커널 쓰레드를 같이 사용하기에 문맥 교환 시 오버헤드로 인해 느리게 작동한다.