- 여태까지 하나의 프로세스는 하나의 제어 스레드를 가지고 프로그램을 실행한다고 가정했다. 그러나 거의 모든 현대의 운영체제는 한 프로세스가 여러 스레드를 포함하는 특성을 가진다.
1. Overview
- 스레드는 CPU이용의 기본 단위이다. 스레드는 스레드 ID, 프로그램 카운터, 레지스터 집합, 그리고 스택으로 구성된다. 한 프로세스에 속한 스레드들은 코드 영역, 데이터 영역, 힙 영역, 파일들 그리고 여러 운영체제 자원들을 공유한다.
- Thread는 PCB에서 Program counter와 레지스터에 대한 정보만 다르다.
A. Motivation
- 현대의 컴퓨터에서, 하나의 application은 다중 스레드를 가진 독립적인 프로세스로 구현된다.
- 프로세스 생성보다 스레드 생성이 더 효율적이다.
- 예를 들어 클라이언트가 웹서버에 여러 요청을 받는 경우 예전같으면 단일 프로세스로 한번에 하나의 클라이언트만 서비스 할 수 있어서 클라이언트는 요청 사항에 대한 응답을 받기까지 매우 긴 시간을 기다려야 했다. 하지만 스레드를 사용하는 경우 Main Thread가 클라이언트에 요청을 수행하는 Worker Thread를 생성하여 클라이언트의 요청을 수행한다.
- 스레드를 사용하면 코드를 단순화 할 수 있고, 효율성을 증대시킬 수 있다.
B. Advantage
- 응답성: 프로세스의 어떤 스레드가 blocked 되어도, 다른 스레드에서 응답이 가능하다.
- 자원 공유: 스레드는 자동적으로 그들이 속한 프로세스의 자원들과 메모리를 공유한다. 이 방법은 프로세스간의 자원 공유(shared data, message passing)보다 더 쉽다.
- 경제성: 프로세스 생성보다 스레드를 생성하고 문맥교환을 하는 것이 더 효율적이다.
- 규모 적응성: 다중 처리기 구조에서 다중 스레드의 이점은 더욱 더 증가한다.
2. Multicore programming(다중 코어 프로그래밍)
- 단일 CPU가 아닌 여러개의 CPU를 가진 시스템을 다중 코어(Multicore) 혹은 다중 처리기(multiprocessor)시스템이라고 부른다.
- 여러 코어를 가진 시스템에서는 각 코어마다 Concurrency하게 Thread가 실행되고 코어가 여러개 이므로 각 코어는 parallelism하게 Thread가 동시에 실행된다.
병렬 실행(parallelism)과 병행 실행(concurrency)
- 병행 실행(concurrenxy)은 여러 프로세스/스레드가 CPU 스케쥴링에 의해 실행되는 것이다.
- 병렬 실행(parallelism)은 다중코어 시스템에서 일어나며 CPU가 여러개 있으니 동시에 실행되는 것이다.
암달의 법칙
- 순차 실행을 하는 구성요소와 병렬 실행을 하는 구성요소로 이루어진 application의 경우 코어수가 늘어날 때 얻을 수 있는 성능을 나타내는 공식이다.
- 순차적으로 실행되는 부분을 S, 코어의 수를 N 이라고 할때 Speedup = 1 / (S + (1 - S) / N)으로 나타낼 수 있다. N이 무한대로 커질때, 성능의 극한값은 1/S이다.
A. Type of Multicore Programming
- Data parallelism: 한 데이터를 부분으로 나누어서 각 CPU에 동일한 연산을 수행하도록 한다.
- Task parallelism: 데이터가 아닌 스레드를 다수의 코어에 분배한다. 그리고 각 스레드는 각자 고유한 연산을 수행한다.
- 실제 application은 이 두가지 병렬 실행을 혼용하여 사용한다.
3. Multi Thread Model(다중 스레드 모델)
- 스레드를 위한 지원은 사용자 수준과 커널 수준에서 제공된다.
- 사용자 수준 스레드는 사용자 수준 스레드 라이브러리에서 관리를 한다.
- 커널 수준 스레드는 커널에서 관리를 한다.
A. Many to one 모델
- 다대일 모델은 많은 사용자 수준 스레드를 하나의 커널 스레드로 mapping한다.
- 이 모델의 경우 하나의 사용자 스레드가 봉쇄형 시스템 호출을 할 경우, 전체 프로세스가 봉쇄된다.
- 한 번에 한 스레드만이 커널에 접근할 수 있기 때문에, 다중 스레드가 다중 코어 시스템에서 병렬로 실행될 수가 없다.
B. one to one 모델
- 각 사용자 스레드를 하나의 커널 스레드로 mapping 한다.
- 하나에 스레드가 봉쇄형 시스템 호출을 하더라도 다른 스레드가 실행될 수 있기 때문에 다대일 모델보다 더 많은 병렬성을 제공한다.
- 또한 이 모델은 다중 처리기에서 다중 스레드가 병렬로 수행되는 것을 허용한다.
- 이 모델의 단점은 하나의 사용자 수준 스레드를 생성 할 때, 그에 따른 커널 스레드를 생성해야 한다는 것이다. 커널 스레드를 생성하는 오버헤드가 응용 프로그램의 성능을 저하시킬 수 있다.
C. many to many 모델
- 여러개의 사용자 수준 스레드를 그보다 작은 수 혹은, 같은 수 의 커널 스레드로 멀티 플렉스 한다.
- 다대다 모델은 다대일 모델에서의 단점(진정한 병렬실행의 불가, 봉쇄형 시스템 호출의 경우 프로세스 봉쇄)과 일대일 모델의 단점(병렬실행을 하다보면 커널 수준 스레드를 많이 생성하여 오버헤드로 인한 성능 저하)을 어느 정도 해결한 모델이다.
- 다대다 모델을 변형한 두 수준 모델(two- level model)은 다대다 모델과 일대일 모델을 동시에 지원한다.
4. Thread Library
- 스레드 라이브러리는 프로그래머에게 스레드를 생성하고 관리하기 위한 API를 제공한다.
스레드 라이브러리 구현의 두가지 방법
- 커널의 지원없이 완전히 사용자 공간에서만 라이브러리를 제공하는 것으로 이 경우 라이브러리를 위한 코드와 자료구조는 사용자 공간에 존재해 함수를 호출하는 것은 시스템 호출이 아니라 사용자 공간의 지역함수를 호출하게 된다.
- 운영체제에 의해 지원되는 커널 수준 라이브러리를 구현하는 것이다. 이 경우 라이브러리를 위한 코드와 자료구조는 커널에 존재해 라이브러리 함수 호출시 커널 System call을 하는 것과 같다.
5. Implicit Threading(암묵적 스레딩)
- Multi Thread Application의 설계를 돕는 한가지 방법은 스레딩의 생성과 관리 책임을 개발자로부터 컴파일러와 runtime 라이브러리에 넘겨주는 것이다. 이 방식은 암묵적 스레딩이라 불린다.
A. Thread Pool
- 스레드를 매 요청마다 만들어 주는 것은, 새 프로세스를 매번 만드는 것보다는 확실히 진보된 방법이지만,,,, 두가지 문제가 있다.
- 그럼에도 불구하고 스레드 생성하는데 소요하는 시간이 든다. 추가로 사용이 끝난 스레드를 삭제하는데 걸리는 시간도 있다.
- 매 요청마다 스레드를 만든다면 최대 스레드 수가 몇개까지 가능할 수 있는 것인지 한계를 정해야한다.
- 그래서 프로세스를 시작할 때, 아예 일정한 수의 스레드들을 미리 풀로 만들어 두어서 스레드 풀에 저장하는 것이다. 그리고 요청을 끝마친 스레드는 다시 스레드 풀로 돌아와 다음 요청을 기다린다.
Advantages
- 새 스레드를 만들어 주는 것보다 기존 스레드로 서비스 해주는 것이 더 빠르다.
- 스레드 풀은 임의의 시간에 존재할 스레드 개수에 제한을 두어 많은 수의 스레드를 병행 처리할 수 없는 시스템에 도움이 된다.