Home [CS] 프로세스와 스레드 03 - 스레드의 개념과 구현
Post
Cancel

[CS] 프로세스와 스레드 03 - 스레드의 개념과 구현

개요

안녕하세요.

이번 글에서는 스레드와 그 구현 방법에 대해 살펴보겠습니다.


스레드 개념

스레드란?

스레드에 대한 소개는 이전 글([CS] 프로세스와 스레드 01 - 프로세스의 기본 개념](/posts/1002_process/))에서 확인할 수 있습니다.

다시 한 번 살펴보자면 다음과 같습니다.

프로세스는 자원과 제어의 특성이 존재합니다.
여기서 제어만 분리한 실행 단위가 스레드(Thread)입니다.

프로세스 1개는 스레드 1개 이상으로 나눌 수 있습니다.

스레드는 보통 다른 프로시저를 호출하고 다른 실행을 기록합니다.

그러므로 별도의 스택이 필요하고, 프로그램 카운터(PC)가 독립적이라서 같은 프로세스의 스레드들이 동시에 코드의 동일한 부분이나 다른 부분을 실행할 수 있습니다.

스레드 중 프로세스의 속성 일부가 들어 있는 것을 경량 프로세스(LWP; Light Weight Process)라고 합니다.

반대로 프로세스 1개에 스레드가 1개인 경우를 중량 프로세스(HWP; Heavy Weight Process)라고 합니다.

같은 프로세스의 스레드들은 다음 그림과 같이 동일한 주소 공간을 공유합니다.

스레드 주소 공간 [그림01] 스레드 주소 공간

스레드 상태 변화

스레드는 프로세스와 유사하게 준비, 실행, 대기(보류), 종료 상태가 있습니다.

프로세스에 있는 스레드는 순차적으로 실행되며 해당 스레드 정보를 저장하는 레지스터와 스택이 존재합니다.

스레드 상태 변화도 [그림02] 스레드 상태 변화도

보통 프로세스를 생성하면 해당 프로세스의 스레드도 생성합니다.

이 때 운영체제는 프로세스가 스택과 레지스터를 제공하므로 프로세스와의 공유자원을 초기화할 필요가 없습니다.

덕분에 프로세스의 생성과 종료보다 오버헤드가 훨씬 적습니다.

여기서 스레드의 장점이 나오는데요.

스레드 1개가 대기 상태로 변할 때 전체 프로세스를 대기 상태로 바꾸지 않는다는 점입니다.

그렇지만 스레드 1개가 다른 스레드의 스택을 읽거나 쓸 수 있어 프로세스와 같이 독립적이지는 않습니다.

스레드 제어블록

프로세스가 프로세스 제어 블록(PCB)를 가지듯 스레드는 스레드 제어 블록(TCB; Thread Control Block)을 갖습니다.

스레드 제어 블록은 다음 내용을 가지고 있습니다.

  • 실행 상태
  • 스케줄링 정보
  • 계정 정보
  • 스케줄링 큐용 다양한 포인터
  • 프로세스 제어 블록을 포함하는 포인터

스레드 제어 블록 [그림03] 스레드 제어 블록


스레드 구현

스레드는 운영체제에 따라 다양하게 구현할 수 있는데 대부분은 다음 3가지 형태로 구현합니다.

  • 사용자 수준 스레드: 다대일(n:1) 매핑
  • 커널 수준 스레드: 일대일(1:1) 매핑
  • 혼합형 스레드: 다대다(n:m) 매핑

사용자 수준 스레드

사용자 수준 스레드(user-level thread)는 사용자 영역의 스레드 라이브러리로 구현하고, 스레드 관련 행위를 사용자 영역에서 하므로 커널이 스레드 존재를 모릅니다.

사용자 수준 스레드 [그림04] 사용자 수준 스레드

스레드 라이브러리는 스레드 생성과 종료, 메시지 전달, 스케줄링과 문맥 등 정보를 보관합니다.

스레드 라이브러리로는 POSIX 표준안인 Pthread, Win32 스레드, 자바 스레드 API 등을 사용합니다.

스레드 교환에 커널이 개입하지 않으므로 커널에서 사용자 영역으로 전환할 필요가 없습니다.

또한 커널은 스레드가 아닌 프로세스를 단위로 인식해 프로세서를 할당합니다.

사용자 수준 스레드는 다음의 장점과 단점을 가집니다.

장점

  • 이식성 우수: 커널에 독립적이고 스케줄링할 수 있으므로 모든 운영체제에 적용할 수 있습니다.
  • 오버헤드 적음: 스케줄링이나 동기화를 위한 커널 호출이 없으므로 커널 영역으로 전환하는 오버헤드가 줄어듭니다.
  • 유연한 스케줄링: 스레드 라이브러리에서 스레드 스케줄링을 제어하므로 응용 프로그램에 맞게 스케줄링 가능합니다.

단점

  • 시스템의 동시성 지원하지 않음: 프로세스 단위로 프로세서를 할당하므로 다중 처리 환경을 갖춰도 스레드 단위로는 다중 처리가 불가능합니다. 예를 들어 스레드 1개가 대기 상태가 되면 이 중 어떤 스레드도 실행하지 못 합니다.
  • 확장에 제약 존재: 다중 처리 시스템에서 규모를 확장하기 어렵습니다.
  • 스레드 간 보호 불가: 스레드 간 보호에 커널의 보호 방법을 사용할 수 없습니다. 스레드 라이브러리에서 스레드 간 보호를 제공해야 프로세스 수준에서 보호가 가능합니다.

커널 수준 스레드

커널 수준 스레드(kernel-level thread)는 사용자 수준 스레드의 한계를 극복하는 방법입니다.

커널이 PCB와 TCB를 유지하며 스레드와 관련된 모든 작업을 수행합니다.

한 프로세스에서 다수의 스레드가 프로세서를 할당받아 병행으로 수행하고, 스레드 1개가 대기 상태가 되면 해당 프로세스의 다르스레드로 교환 가능합니다.

이 때도 커널이 개입하므로 사용자 영역에서 커널 영역으로 전환이 필요합니다.

커널 수준 스레드에서는 다음 그림과 같이 사용자 수준 스레드와 커널 수준 스레드가 일대일(1:1)로 매핑됩니다.

커널 수준 스레드 [그림05] 커널 수준 스레드

커널 수준 스레드는 다음의 특징을 가집니다.

  • 다중 프로그래밍 수준 향상: 커널이 각 스레드를 개별 관리해 동일한 프로세스릐 스레드들을 병행으로 수행할 수 있습니다.
  • 오버헤드 증가: 커널 영역으로 전환하는 오버헤드가 발생하며 스케줄링과 동기화에 더 많은 자원이 필요합니다.

혼합형 스레드

혼합형 스레드는 사용자 수준 스레드와 커널 수준 스레드를 혼합한 구조입니다.

시스템 호출을 할 때 다른 스레드를 중단하는 다대일(n:1) 매핑의 사용자 수준 스레드와 스레드 수를 제한하는 일대일(1:1) 매핑의 커널 수준 스레드 문제를 극복하는 방법입니다.

사용자 수준 스레드는 커널 수준 스레드와 비슷한 경량 프로세스에 다대다(n:m) 매핑되고, 경량 프로세스는 커널 수준 스레드와 일대일(1:1) 매핑됩니다.

커널 수준 스레드는 프로세서에서 실행하지만 경량 프로세스는 시스템 호출로 생성해서 커널 영역의 프로레스 문맥 안에서 실행하고, 커널로 독립적으로 스케줄링하여 다중 처리에서는 병렬로 실행합니다.

혼합형 스레드 [그림06] 혼합형 스레드

위 그림의 각 프로세스를 살펴보면 다음과 같습니다.

왼쪽 - 1:1 매핑

사용자 수준 스레드 1개를 경량 프로세스 1개에 연결한 전통적인 유닉스 단일 프로세스 형태입니다.

중간 - n:m 패핑

사용자 수준 스레드 3개가 경량 프로세스 2개에 매핑된 모습입니다.

오른쪽 - 복잡한 매핑

사용자 수준 스레드와 경량 프로세스를 각각 매핑한 형태입니다.

사용자 수준 스레드 1개와 연결한 경량 프로세스는 특정 프로세서 하나로 스케줄링하지 않습니다.

사용자 수준 스레드는 스레드 라이브러리가 스케줄링하고 커널 스레드는 커널이 스케줄링하면서 커널이 사용자 수준 스레드와 커널 수준 스레드의 매핑을 적절히 조절합니다.


다중과 관련된 용어 정리

다중 관련 용어 정리 [그림07] 다중 관련 용어 정리

다중 처리

다중 처리(Multi Processing)은 프로세서 1개 이상이 서로 협력하는 처리를 뜻합니다.

이 때 프로세서는 컴퓨터 1대에 있을 수도, 여러 대에 있을 수도 있습니다.

따라서 다중 처리는 컴퓨터로 나누기보다 프로세서 1개 이상이 작업을 병렬 처리하는 것으로 정의하면 더 정확합니다.

다중 프로그래밍

다중 프로그래밍(Multi Programming)은 프로세서가 입출력 작업의 응답을 대기할 동안 다른 프로그램을 실행할 수 있도록 하는 것입니다.

프로세서의 자원 낭비를 최소화하려고 낭비하는 시간 동안 다른 프로세스를 실행해 프로세서 하나에서 여러 프로세스를 교대로 수행합니다.

다중 작업

다중 작업(Multi Tasking)은 작업이 프로세서 하나에서 운영체제의 스케줄링에 따라 조금씩 번갈아 가면서 수행하는 것입니다.

조금씩 아주 빠르게 동작하여 사용자는 동시에 동작하는 것처럼 느낍니다.

다중 프로그래밍이 자원 낭비의 최소화를 위해 교대로 작업한다면 다중 작업은 정해진 시간동안 교대로 작업을 수행합니다.

다중 스레드

다중 스레드(Multi thread)는 프로세스 하나에서 스레드를 여러 개 동시에 실행하는 것입니다.

이 스레드들은 공유 메모리 하나를 가져 정보 교환에 제한이 없습니다.

반면 다중 작업은 운영체제에서 지원하므로 IPC(Inter-Process Communication)를 구현해 자원을 전달해야 합니다.

하지만 다중 작업은 메모리를 독립적으로 사용할 수 있으므로 용도에 맞춰 적절히 사용해야 합니다.


마무리하며

이번 글에서는 스레드에 대해 살펴보았습니다.

스레드는 하나의 실행 단위로 스레드 제어블록, 상태변화 등 프로세스와 유사한 특징을 보입니다.

하지만 구현에 있어서는 많은 차이를 보입니다.

크게 사용자 수준, 커널 수준, 혼합형 스레드로 구분되는 구현 방식이 존재하며 그에 따라 장단점이 존재합니다.

이 글이 조금이나마 도움이 되셨으면 합니다.

감사합니다. 😀


참고 문헌

  • 구현회, 그림으로 배우는 구조와 원리 운영체제, 한빛아카데미, 2016
This post is licensed under CC BY 4.0 by the author.

[Develop] POSIX

[CS] 프로세스와 스레드 04 - 프로세스와 상호배제

Comments powered by Disqus.