본문 바로가기

프로그래밍/운영체제(OS)

Threads

Overview

- Threads는 CPU 이용의 기본 단위이다.

- Threads는 Threads ID, Program Counter, Register Set, Stack으로 구성된다.

- Threads는 같은 프로세스에 속한 다른 Threads와 Code, Data Section, 열린 파일이나 신호와 같은 운영체제 자원들을 공유한다.

- 프로세스가 다중의 스레드를 가진다면, 프로세스는 동시에 하나 이상의 작업들을 수행할 수 있다.

Motivation(동기)

- 하나의 응용프로그램이 여러 개의 비슷한 작업들을 수행할 필요가 있는 상황

- 하나의 응용프로그램은 여러 개의 실행 흐름을 가진 독립적인 프로세스로 구현

- 스레드는 원격 프로시저 호출(RPC, Remote Procedure Call)에서 중요한 역할을 담당

- 다수의 운영체제 커널은 현재 다중화 되어 있음

장점

- 응답성(Responsiveness) : 대화형 응용을 다중 스레드화하면 응용 프로그램의 일부분이 봉쇄되거나, 또는 응용 프로그램이 긴 작업을 수행하더라도 프로그램의 수행이 계속되는 것을 허용함으로써, 사용자에 대한 응답성을 증가시킴

 

- 자원 공유(Resource Sharing) : 프로세스는 공유 메모리와 메시지 전달 기법을 통하여만 자원을 공유할 수 있다. 하지만 스레드는 자동적으로 그들이 속한 프로세스의 자원들과 메모리를 공유한다. 코드와 데이터 공유의 이점은 한 응용 프로그램이 같은 주소 공간 내에 여러 개의 다른 작업을 하는 스레드를 가질 수 있다는 것이다.

 

- 경제성(Economy) : 프로세스 생성을 위해 메모리와 자원을 할당하는 것은 비용이 많이 든다. 하지만 스레드는 자신이 속한 프로세스의 자원들을 공유하기 때문에, 스레드를 생성하고 문맥 교환하는 것이 더 경제적이다.

 

- 규모 적응성(Scalability) : 다중 스레드의 이점은 다중 처리기 구조에서 더욱 증가한다. 다중 처리기 구조에서는 각각의 스레드가 다른 처리기에서 병렬로 수행될 수 있기 때문이다. 단일 스레드 프로세스는 처리기가 아무리 많더라도 오직 한 처리기에서만 실행된다.

다중코어 프로그래밍

코어가 여러 CPU칩 형태를 띠거나 칩 안에 여러 개가 존재하든지 이러한 시스템을 다중코어 또는 다중 처리기 시스템이라고 정의한다.

다중 스레드 프로그래밍은 다중 계산 코어를 더 효율적으로 사용할 수 있고 병행 실행을 더 향상시킬 수 있는 기법을 제공한다.

병렬 실행 : 하나 이상의 태스크를 동시에 수행할 수 있는 시스템

병행 실행 : 모든 태스크가 진행하게끔 함으로써 하나 이상의 태스크를 지원

다중 코어 시스템 프로그래밍 도전과제

- 태스크 인식(Identifying tasks) : 응용을 분석하여 독립된 병행가능 태스크로 나눌 수 있는 영역을 찾는 작업이 필요. 이상적으로는 태스크는 서로 독립적이고 따라서 개별 코어에서 병렬 실행 될 수 있어야 함.

 

- 균형(Balance) : 병렬로 실행될 수 있는 태스크를 찾아내는 것도 중요하지만 찾아진 부분들이 전체 작업에 균등한 기여도를 가지도록 태스크로 나누는 것도 매우 중요. -> 어떤 경우에는 다른 태스크에 비해 기여도가 적은 작업이 있을 수 있으며 이러한 작업을 실행하기 위해 별도의 코어를 사용하는 것은 가치가 없다.

 

- 데이터 분리(Data Spliting) : 응용이 독립된 태스크로 나누어지는 것처럼, 태스크가 접근하고 조작하는 데이터 또한 개별 코어에서 사용할 수 있도록 나누어져야 한다.

 

- 데이터 종속성(Data dependency) : 태스크가 접근하는 데이터는 둘 이상의 태스크 사이에 종속성이 없는지 검토되어야 한다. 한 태스크가 다른 태스크로부터 오는 데이터에 종속적인 경우에는 프로그래머가 데이터 종속성을 수용할 수 있도록 태스크의 수행을 잘 동기화해야 한다.

 

- 시험 및 디버깅(Testing and Debugging) : 프로그램이 다중코어에서 병렬로 실행될 때, 다양한 실행 경로가 존재 할 수 있다. 그런 병행 프로그램을 시험하고 디버깅하는 것은 단일 스레드 응용을 시험하고 디버깅하는 것보다 근본적으로 훨씬 어렵다.

병렬 실행의 유형

데이터 병렬 실행 : 동일한 데이터의 부분집합을 다수의 계산 코어에 분배한 뒤 각 코어에서 동일한 연산을 실행하는 데 초점을 맞춘다. 데이터가 코어에 분배되어야 한다.

태스크 병렬 실행 : 데이터가 아니라 태스크(스레드)를 다수의 코어에 분배한다. 각 스레드는 고유의 연산을 실행한다. 태스크가 코어에 분배되어야 한다.

다중 스레드 모델(Multithreading Models)

사용자 스레드(user threads)를 위해서는 사용자 수준에서, 또는 커널 스레드(kernel threads)를 위해서는 커널 수준에서 제공된다.

사용자 스레드는 커널 위에서 지원되며 커널의 지원 없이 관리된다. 반면에 커널 스레드는 운영체제에 의해 직접 지원되고 관리된다

다대일 모델(Many-to-One Model)

많은 사용자 수준 스레드를 하나의 커널 스레드로 사상한다.

스레드 관리는 사용자 공간의 스레드 라이브러리에 의해 행해진다. 따라서 효율적이다.

하지만 한 스레드가 봉쇄형 시스템 콜을 할 경우, 전체 프로세스가 봉쇄된다. 또한 한 번에 하나의 스레드만이 커널에 접근할 수 있기 때문에, 다중 스레드가 다중코어 시스템에서 병렬로 실행될 수 없다. 그린 스레드(green thread)가 다대일 모델을 사용하였는데, 다중 처리 코어의 이점을 살릴 수 없기 때문에 이 모델을 사용 중인 시스템은 거의 존재하지 않는다.

일대일 모델(One-to-One Model)

각 사용자 스레드를 각각 하나의 커널 스레드로 사상한다.

하나의 스레드가 봉쇄적 시스템 콜을 호출하더라도 다른 스레드가 실행될 수 있기 때문에 다대일 모델보다 더 많은 병렬성을 제공한다. 또한 이 모델은 다중 처리기에서 다중 스레드가 병렬로 수행되는 것을 허용한다.

이 모델의 단 하나의 단점은 사용자 수준 스레드를 생성할 때 그에 따른 커널 스레드를 생성해야 한다는 점이다. 커널 스레드를 새엉하는 오버헤드가 응용 프로그램의 성능을 저하시킬 수 있으므로, 이 모델의 대부분의 구현은 시스템에 의해 지원되는 스레드의 수를 제한한다. Windows 계열의 운영체제와 Linux가 일대일 모델을 구현하고 있다.

다대다 모델(Many-to-Many Model)

여러 개의 사용자 수준 스레드를 그보다 작은 수 혹은, 같은 수의 커널 스레드로 멀티플렉스 한다.

커널 스레드의 수는 응용 프로그램이나 특정 기계에 따라 결정된다.(응용 프로그램은 단일 처리기보다 다중 처리기에서 더 많은 커널 스레드를 할당받을 수 있다.)

 

다대일 모델은 개발자가 원하는 만큼의 사용자 수준 스레드를 생성하도록 허용하지만, 한 번에 하나의 스레드만이 커널에 의해서 스케줄 되기 때문에 진정한 병렬 실행을 획득할 수 없다.

일대일 모델은 더 많은 병행 실행을 제공하지만, 개발자가 한 응용 내에 너무 많은 스레드를 생성하지 않도록 주의해야 한다.(그리고 몇몇 시스템에서는 생성할 수 있는 스레드의 수가 제한될 수 있다.)

다대다 모델은 이러한 두 가지의 단점들을 어느 정도 해결했다. 개발자는 필요한 만큼 많은 사용자 수준 스레드를 생성할 수 있다. 그리고 상응하는 커널 스레드가 다중 처리기에서 병렬로 수행될 수 있다. 또한 스레드가 봉쇄형 시스템 콜을 발생시켰을 때, 커널이 다른 스레드의 수행을 스케줄 할 수 있다.

다대다 모델의 변형[두 수준 모델 (two-level model)]은 여전히 많은 사용자 스레드를 적거나 같은 수의 커널 스레드로 멀티플렉스 시키지만 한 사용자 스레드가 하나의 커널 스레드에만 연관되는 것을 허용한다.

스레드 라이브러리(Threads Library)

프로그래머에게 스레드를 생성하고 관리하기 위한 API를 제공한다.

- 커널의 지원 없이 완전히 사용자 공간에서만 라이브러리 제공 -> 시스템 호출이 아닌 사용자 공간의 지역 함수를 호출

- 운영체제에 의해 지원되는 커널 수준 라이브러리 구현 -> 커널 시스템 호출

요약

- 스레드는 프로세스 안의 제어 흐름이다.

- 다중 스레드 프로세스는 같은 주소 공간 안에 여러 개의 서로 다른 제어 흐름을 가지고 있다.

- 다중 스레딩의 장점은 사용자에 대한 향상된 응답성, 프로세스 내의 자원 공유, 경제성 및 더 효율적인 다중 처리 코어의 이용과 같은 규모 적응성 요소 등이다.

- 사용자 수준 스레드는 프로그래머에게는 보이나, 커널은 알 수가 없는 스레드이다.

- 커널 수준 스레드는 운영체제 커널에 의해서 지원되며 관리된다.

- 일반적으로, 커널의 개입을 필요로 하지 않기 때문에 사용자 수준 스레드는 커널 수준 스레드보다 빠르게 생성되고, 빠르게 관리된다. 

- 다대일 모델은 여러개의 사용자 스레드를 하나의 커널 스레드로 사상한다.

- 일대일 모델은 각 사용자 스레드를 그에 대응하는 커널 스레드로 사상한다.

- 다대다 모델은 많은 사용자 스레드를 그보다 적거나 같은 수의 커널 스레드로 멀티플렉스한다.