스레드란 무엇인가
10 Mar 2022스레드란?
클라이언트로부터 여러가지 요청을 받는 분주한 웹 서버가 단일 스레드 프로세서로 작동한다면, 자신의 단일 프로세스로 한 번에 하나의 클라이언트만 서비스할 수 있다. 즉, 서버에게 서비스 요청이 들어오면, 프로세스는 그 요청을 실행할 별도의 프로세스를 생성하는 것이다.
프로세스의 메모리 구조는 전역변수가 할당하는 데이터 영역, malloc 함수 등에 의해 동적 할당이 이뤄지는 힙영역, 그리고 함수의 실행에 사용되는 스택으로 이뤄진다.
위 그림처럼 여러 개의 프로세스를 실행시켜 독립적인 메모리 공간을 사용하면 IPC를 통하지 않고는 통신할 수 없다. 또한 독립적인 메모리 공간으로 컨텍스트 스위칭이 발생한다. 이러한 문제점을 스레드가 해결해준다.
스레드는 하나의 프로그램 내에 여러 개의 실행 흐름을 위한 모델이다. 우리가 생각하는 프로그램이 실행되기 위해서 하나의 실행흐름으로 처리할 수도 있지만 다수의 실행흐름으로 처리할 수도 있다.
멀티 스레드
프로세스를 여러 개 생성하는 방식은 매우 많은 시간을 소비하고 많은 자원을 필요로한다. 하지만 새 프로세스가 해야 할 일이 기존 프로세스가 하는 일과 동일하다면, 새로운 프로세스를 생성하거나 두 프로세스 사이에서 데이터 교환을 위한 IPC 기법을 적용하기 보다 프로세스 안에 여러 스레드를 만들어 나가는 것이 더 효율적이다.
멀티 스레드의 장점은 아래와 같다.
- 응답성: 대화형 응용 프로그램을 다중 스레드화하면 응요 프로그램의 일부분이 봉쇄되거나, 또는 응요 프로그램이 긴 작업을 실행하더라도 프로그램의 실행이 계속되는 것을 허용함으로써 사용자에 대한 응답성을 증가시킨다.
- 자원 공유: 스레드는 자동적으로 그들이 속한 프로세스의 자원들과 메모리를 공유한다. 코드와 데이터 공유의 이점은 한 응용 프로그램이 같은 주소 공간 내에 여러 개의 다른 작업을 하는 스레드를 가질 수 있다는 점이다.
- 경제성: 프로세스 생성을 위해 메모리와 자원을 할당하는 것은 비용이 많이 든다. 스레드는 자신이 속한 프로세스의 자원들을 공유하기 때문에 스레드를 생성하고 문맥을 교환하는 것이 보다 더 경제적이다.
- 규모 가변성: 단일 스레드 프로세스는 CPU가 아무리 많더라도 오직 한CPU에서만 실행된다. 다중 CPU에서 다중 스레딩은 병렬성을 증가시킨다.
다중스레드 모델
스레드를 위한 지원은 사용자 스레드를 위해서는 사용자 수준에서, 또는 커널 스레드를 위해서는 커널 수준에서 제공된다. 사용자 스레드는 커널 위에서 지원되며 커널의 지원 없이 관리된다. 반면에 커널 스레드는 운영체제에 의해 직접 지원되고 관리된다.
사용제 스레드와 커널 스레드는 어떤 연관 관계가 존재해야 한다.
-
다대일 모델(Many-to-One Model)
많은 사용자 수준 스레드를 하나의 커널 스레드로 사상한다. 스레드 관리는 사용자 공간의 스레드 라이브러리에 의해 행해진다. 따라서 효율적이라 할 수 있지만, 한 스레드가 봉쇄형 시스템 호출을 할 경우 전체 프로세스가 봉쇄된다. 또한 한 번에 하나의 스레드만이 커널에 접근할 수 있기 때문에 다중 스레드가 다중 처리기에서 돌아도 병렬로 작동할 수 없다.
Solaris의 스레드 라이브러리와 GNU Portable 스레드도 이 모델을 사용한다
-
일대일 모델(One-to-One Model)
각 사용자 스레드를 각각 하나의 커널 스레드로 사상한다. 이 모델은 스레드가 봉쇄적 시스템 호출을 호출하더라도 다르 스레드가 실행될 수 있기 때문에 다대 일 모델보다 더 많은 병렬성을 제공한다. 또한 이 모델은 다중처리기에서 다중 스레드가 병렬로 실행되는 것을 허용한다. 이 모델의 단점은 사용자 수준 스레드를 생성할 때 그에 따른 커널 스레드를 생성해야 한다는 점이다.
Windows와 Linux가 일대일 모델을 구현하고 있다
-
다대다 모델(Many-to-Many Model)
여러 개의 사용자 수준 스레드를 그보다 작은 수 혹은, 같은 수의 커널 스레드로 멀티플렉스한다. 다대일 모델은 개발자가 원하는 만큼의 사용자 수준 스레드를 생성하도록 허용하지만, 한 번에 하나의 스레드만이 커널에 의해서 스케줄되기 때문에 진정한 동시성을 획득할 수 없다. 일대일 모델은 더 많은 병렬성을 제공하지만, 개발자가 한 응용 프로그램 내에 너무 많은 스레드를 생성하지 않도록 주의해야 한다.
다대다 모델은 이러한 두가지의 단점들을 어느 정도 해결했다. 개발자는 필요한 만큼 사용자 수준의 스레드를 생성할 수 있다. 또한, 스레드가 봉쇄형 시스템 호출을 발생시켰을 때, 커널이 다른 스레드의 실행을 스케줄할 수 있다.
HP-UX 그리고 Tru64 UNIX가 이 모델을 지원한다
동시성(Concurrency) 병렬성(Parallelism)
동시성이란 하나의 프로세서 / 코어를 사용하여 둘 이상의 작업을 지원할 때 사용하는 것을 의미한다.
병렬성은 동시에 둘 이상의 작업을 수행할 수 있음을 의미한다.
대부분의 단일 코어 컴퓨터 시스템과 CPU 스케줄러는 빠르게 프로세스를 스위치 하면서 병렬성을 보장하는 것처럼 보이게 하였다.
병렬성에는 두가지 종류가 있다.
- Data Parallelism - 하나의 데이터를 여러 개의 코어로 나누어서, 각각 같은 동작을 한다.
- N개의 인덱스를 더하기 위한 Data Paralleism
- [0] + [1] + … + [N/2 - 1]
- [N/2] + [N/2 + 1] + … + [N - 1]
- Task Paralleism - 스레드를 분산시켜 여러개의 코어로 나누어, 각각 필요한 동작을 한다.
스레드 라이브러리
스레드 라이브러리는 프로그래머에게 스레드를 생성하고 관리하기 위한 API를 제공한다. 스레드 라이브러리를 구현하는 데에는, 커널의 지원없이 완전히 사용자 공간에서만 라이브러리를 제공하는 방법과 운영체제에 의해 지원되는 커널 수준 라이브러리를 구현하는 방법이 있다.
컨러 수준 라이브러리의 경우, 라이브러리를 위한 코드와 자료 구조는 커널 공간에 존재한다. 라이브러리 API를 호출하는 것은 커널 시스템 호출을 부르는 결과를 낳는다.
POSIX Pthreads
Pthreads는 사용자 또는 커널 수준 라이브러리로서 제공될 수 있다. 이는 스레드 생성과 동기화를 위해 제정한 표준 API이며, 이것은 스레드의 동작에 관한 명세일 뿐이지 그것 자체를 구현한 것은 아니다. 이 명세를 가지고 운영체제 설계자들은 나름의 방식대로 구현할 수 있다. Solaris, Linux, Mac OS X 및 Tru64 UNIX를 포함한 많은 시스템들이 PThreads 명세를 구현하고 있다.
질문
-
사용자 스레드와 커널 스레드의 차이
사용자 스레드는 커널이 인식할 수 없지만 커널은 커널 스레드를 인식한다. 커널 스레드는 프로세스와 연결할 필요가 없다. 반면 모든 사용자 스레드는 프로세스에 속한다.
-
프로세스를 만들 때와 스레드를 만들 때의 차이
프로세스를 생성하기 위해서는 프로세스 제어 블록을 할당해야 한다. 메모리 맵, 파일 목록, 환경 변수 등 메모리 맵 할당 및 관리는 상당히 시간을 소비하는 활동이다. 스레드를 생성하는 것은 레지스터를 셋을 보유하기 위한 작은 데이터 구조와 스택, 우선순위가 있다.
참고자료 :
https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQLqTv4J6fdJao-Ynd7TGw9Ix9y_GXb7ZKeCw&usqp=CAU