본문 바로가기

CS/운영체제

[ 운영체제 ] 쓰레드(Thread)

반응형

Thread 등장 배경

쓰레드는 프로세스의 단점을 보완한 새로운 실행 단위다. 사실 이전에 프로세스가 CPU의 실행 단위라고 했는데 사실은 쓰레드가 맞다. 이전까지는 엄밀히 말해서 '단일 쓰레드'라고 할 수 있다. 프로세스의 치명적인 단점은 fork()를 할 때 자식 프로세스에게 code~stack까지의 모든 메모리 공간을 새롭게 할당한다는 점이다. 이는 심각한 메모리 낭비다. 이해하기 쉽게 그림으로 알아보자.

 

부모 프로세스에 의해 생성된 자식 프로세스

 

위 그림과 같이 fork()에 의해 생성된 프로세스는 모두 새로운 메모리 공간을 할당받았다. 그런데 크롬창 네 개를 실행시키는 경우를 생각해보자. 같은 프로그램이기 때문에 비슷한 부분이 상당히 많을 것이다. 어떤 부분이 같고, 어떤 부분이 다를까? 

 

 

그렇다.. 사실 stack 부분만 달라도 상관 없다. 조금 더 자세하게 들어가면 CPU register, stack, program counter 값은 달라야 한다. 하지만 text~heap 부분은 같아도 상관 없다. 그러면 공유 하는 부분은 같이 쓰고, 따로 쓰는 부분만 구분하면 되지 않을까? 그래서 나온 게 쓰레드다. 쓰레드의 구조는 아래와 같다. 

 

쓰레드의 구조

 

이제 프로세스는 그냥 쓰레드를 담는 컨테이너로 생각하면 된다. CPU의 실행 단위는 프로세스가 아니라 쓰레드다! 이제 쓰레드의 장점을 하나씩 살펴보자.

1. 복잡한 프로그램(프로세스)은 쓰레드를 통해 일을 분담할 수 있다.

한 개의 프로세스에 여러 개의 쓰레드가 있고 CPU가 여러 개 있다면, 프로세스 안에 있는 쓰레드들은 각각 CPU를 사용할 수 있다. 동시에 여러 가지 일을 처리할 수 있기 때문에 비동기 효과도 있다. 복잡한 프로그램을 싱글 쓰레드로 실행시키면 한 번에 한 가지 일만 처리할 수 있기 때문에 속도가 굉장히 느려진다. 예를 들어 프린트를 해야할 일이 생기면 프린트가 끝날 때까지 다른 작업을 수행하지 못한다.

2. IPC가 필요 없다.

쓰레드는 서로 메모리 공간을 공유하기 때문에 직접적인 통신이 가능하다. 

3. 새로운 쓰레드를 생성할 때 프로세스는 PC와 스택 공간만 할당해주면 된다.

4. Cache Flush 과정이 없기 때문에 Context Switch 속도가 빠르다. 

  • Process Context Switching → CPU 교체 + Cache flush
  • Thread Context Switching → CPU 교체
  • CPU 교체 시간은 동일하다

한 가지 유의할 점은, 1~4번 모두 같은 프로세스 안에 있는 쓰레드일 경우에만 해당된다.

 

 

그렇다면 쓰레드는 누가 관리할까? 프로세스는 PCB에 의해 관리된다. 쓰레드도 똑같이 TCB라는 녀석이 관리한다. 이름이 Process에서 Thread로 바꼈을 뿐이다. TCB는 PCB에 연결 리스트 형태로 붙어있다. 그림으로 보면 아래와 같다.

 

TCB의 모습

Kernel Thread vs User Thread

1. Kernel Thread

지금까지 다룬 내용이 kernel thread에 관한 내용이다. 말 그대로 커널에 의해 관리되는 쓰레드다. 사실 TCB가 등장한 순간 이미 커널이 관리한다는 것을 뜻한다. kernel thread는 시스템 콜에 의해 생성된다. kernel thread의 장점은 위에서 다룬 내용과 일치한다. 그렇다면 단점은 무엇일까?

 

kernel thread는 커널이 관여하기 때문에 시스템 콜에 의한 오버헤드가 발생한다. 또한 쓰레드끼리도 context switch를 해줘야 하기 때문에 context switch에 의한 오버헤드도 발생한다. 

2. User Thread

사용자 라이브러리로 구현된 쓰레드다. 커널이 관여하지 않기 때문에 커널 관점에서는 하나의 쓰레드지만, 프로그램 레벨에서는 다른 쓰레드다. 그림으로 나타내면 아래와 같다.

 

 

user thread는 mode bit의 변경이 없기 때문에 굉장히 빠르다. 하지만 커널 관점에서 하나의 쓰레드기 때문에 user thread 한 개가 block 되면 나머지 user thread도 block 된다. 또한 user thread끼리는 다른 CPU 코어에 할당될 수 없다. 왜냐하면 컴퓨터의 실행 단위는 kernel thread이기 때문이다. 물론 이러한 단점들은 같은 kernel thread에 속하는 user thread일 때만 해당된다. 그리고 무엇보다... 구현하기 굉장히 어렵고 복잡하다. 

 

 

 

 

 

반응형