Shine's dev log

쓰레드(Thread)_2 (multi threading models) 본문

운영체제

쓰레드(Thread)_2 (multi threading models)

dong1 2020. 4. 27. 00:30

1. Thread Library

 

우리가 실제로 코딩을 할 때, 쓰레드를 새로 만들거나 관리하고싶다면 Thread library를 살펴봐야한다.

 

리눅스계열에서는 Pthread라는 라이브러리를 사용하는데, 이 라이브러리는 운영체제가 주는 기능들을 쓸 수 있게  API를 제공해준다.

 

Pthread 에서는 쓰레드 creation, synchronization 등과 같은 여러 기능들을 제공해주는데, 일정한 standard만 정의되어 있을 뿐, 직접적으로 구현하는것은 사용자들의 몫이다.

 

 

 

2. 쓰레드를 보는 두가지 관점

 

우리가 멀티쓰레드 모델을 살펴보기 전에, 쓰레드를 보는 두가지 관점을 먼저 알아봐야한다.

 

쓰레드는 운영체제가 볼때와 어플리케이션이 볼 때 그 모양이 다를 수 있다. 이는 kernel thread와 user thread가  mapping되어서 동작하는데, 무조건 일대일 대응이 아니기 때문에 발생한다.

 

1) kernel threads (운영체제가 보는 쓰레드)

 

kernel thread는 운영체제가 직접적으로 관리하는 쓰레드이다.

 

가장 중요한 것은 kernel thread는 스케쥴링의 기본 단위가 된다는 것이다. 이 말은 쉽게말하면, 하나의 코어에 하나의 쓰레드가 들어간다는 뜻이다.

 

2) user threads (응용프로그램이 보는 쓰레드)

 

user thread는 user-level에서 library를 쓰는 형식으로 사용된다. user thread는 kernel thread 위에서 동작한다.

 

예를들어 10개의 user thread를 1개의 kernel thread 위에서 돌릴 수 있다는 말이다.

 

 

 

3. multi-threads model

 

그렇다면 user thread와 kernel thread 가 어떤 모델로 mapping되어있는지 그 유형을 살펴보자.

 

1) one - to - one

 

가장 일반적이고 거의 대부분의 OS에서는 one to one 모드를 지원한다.

 

one - to - one모델에서는 유저가 보는 쓰레드가 커널에서 보는 쓰레드와 일치한다. 그래서 user level에서 쓰레드를 생성하면 kernel level에서도 똑같이 하나의 쓰레드가 생성된다.

 

one - to - one

 

이 경우, many - to - one 모델보다는 concurrency를 더 살릴 수 있다는 장점이 있지만,

 

너무 많은 쓰레드들이 생길경우 스케쥴링에 문제가 생기므로, 운영체제가 함부러 쓰레드를 생성하는것을 제한하는 경우가 많다.

 

2) many - to - one

 

앞서 살펴본 one - to - one 모델에서는 유저가 마구잡이로 쓰레드를 생성하는것을 제한한다. 하지만 many - to - one 모델에서는 하나의 kernel thread를 가지고 여러개의 user thread를 생성한다.

 

many - to - one

 

아무래도 하나의 kernel thread에서 파생된것이다 보니, user thread끼리 context switching이 손쉽게 처리된다는 장점이 있다.

 

그러나 하나의 kernel thread가 문제가 생기면 여러개의 user thread들이 모두 먹통이 된다는 치명적인 단점이 있다.

 

또한, user level에서는 여러개의 쓰레드로 보이지만, 실제 kernel thread는 하나이기 때문에 (운영체제는 하나의 쓰레드로 보기 때문에) 아무리 코어가 여러개더라도 parallel 하게 쓰레드를 관리할 수 없다.

 

3) many - to - many

 

여러개의 user thread가 여러개의 kernel thread에 mapping 되는 형태. 

 

운영체제에게 충분한 양의 kernel thread를 생성할 수 있게 해준다.

 

4) Two - level model

 

여러가지 모델들을 짬뽕한 형태의 모델이다.

 

 

 

4. Implicit Threading

 

앞서 설명한 쓰레드는 모두 explicit thread이다.

 

Implicit Threading이란, 우리가 직접 쓰레드를 생산, 관리하는 것이 아니라 운영체제에게 쓰레드 생산, 관리를 맡기는 것이다. 그래서 프로그래머가 직접 만드는것이 아니라 컴파일러에 의해 쓰레드가 관리된다.

 

Implicit Threading 에는 크게 4가지 방법들이 있는데, 하나씩 간단히 살펴보자.

 

1) Thread Pool

 

프로세스 시작 시 미리 쓰레드들을 Pool로 만들어 놓고, 필요시마다 하나씩 가져다 쓰고 반납하는 형태이다. 미리 만들어놓기 때문에 빠르고, 다양한 기능들을 사용할 수 있다.

 

2) Fork Join

 

메인 쓰레드가 여러개의 자식쓰레드들을 만들고(fork) 자식 쓰레드들이 일을 마치고 다시 합쳐지는(join) 형태이다.

 

3) open MP

 

쓰레딩을 language 수준에서 미리 기술하는 방법이다. parallel regions를 미리 정하는 형태로 동작하는데, 주로 #progma 코드를 이용하여 parallel regions를 정의해준다.

 

4) Grand Central Dispatch(GCD)

 

주로 Mac OS X 와 IOS 에서 자주 사용하는방식으로 parallel하게 처리할 블록을 지정하고 parallel하게 처리할 수 있는 dispatch queue에 assign 시켜 병렬적으로 사용하는 방법이다.

 

 

오늘 내용을 정리해보면,

 

1. 쓰레드는 라이브러리를 이용하여 구현된다.

 

2. 쓰레드는 운영체제 관점에서 보는 kernel thread와 응용프로그램 관점에서 보는 user thread로 나뉜다.

 

3. 이 kernel thread와 user thread를 다양한 방법으로 조합한 모델들이 존재하는데, one-to-one이 가장 일반적이다.

 

4. Implicit threading를 이용하면 운영체제에게 쓰레드 관리를 맡길 수 있다.

 

 

본 내용은 공부하며 작성한 것으로, 치명적인 오류가 있을 수 있습니다.

'운영체제' 카테고리의 다른 글

프로세스 스케줄링_1  (0) 2020.05.04
쓰레드(Thread)_3 (Issues in Threading)  (0) 2020.04.28
Concurrency와 Parallelism  (0) 2020.04.26
쓰레드(Thread)_1 (쓰레드란?)  (3) 2020.04.26
UNIX 의 파일 처리  (0) 2020.04.15