1. 스레드란?
- 스레드의 정의는 프로세스 내부에서 실행되는 실행 흐름의 단위이다.
- 정의는 위와 같지만 어렵기 때문에 스레드는 한 프로세스 내부의 자원을 공유하면서 프로세스를 여러개로 쪼개서 실행시키는 것을 말한다.
- 프로세스끼리는 서로 자원 공유를 못하지만 스레드는 한 프로세스 내에 여러개가 존재하기 때문에 한 프로세스의 자원을 공유할 수 있다. 이처럼 한 프로세스 내에 여러개의 스레드가 존재하는 것을 멀티 스레드라고 한다.
- 싱글 스레드는 일반적인 프로세스 구조이기 때문에 이 포스팅에서는 멀티스레딩에 대해서 설명할 것이다.
2. 멀티 스레드(Multi Thread)란?
- 위에서 설명한 것과 같이 한 프로세스 내에서 여러개의 스레드가 존재하는 것을 멀티 스레드라고 한다.
- 스레드 입장에서 보면 프로세스는 스레드들이 일하는 공장이고 스레드는 프로세스라는 공장에서 일하는 일꾼들이다.
- 아래의 그림이 싱글 스레드와 멀티 스레드의 차이를 가장 잘 나타내는 그림인 것 같다.
스레드는 한 프로세스 내부의 자원을 공유한다고 했다. 그 말은 그림과 같이 프로세스의 code, data와 같은 부분은 모든 스레드가 접근할 수 있다.(PID가 같음) 하지만 PC와 레지스터정보, 스택은 각 스레드마다 개별적으로 존재해야 한다.
이유를 생각해보면 한 프로세스, 즉 하나의 코드 파일을 여러개의 스레드가 나눠서 실행하기 때문에 해당 함수에 맞는 지역변수, 함수 호출 정보를 저장하고 각자의 수행 컨텍스트를 유지해야 하기 때문에 개별적인 스택을 갖고 있는게 좋다!
만약 스택을 공유한다면?
만약 멀티코어 환경이라면 다른 스레드와 같이 일을 하기 때문에 다른 스레드에서 공유 스택을 변경하게 되면 내부적으로 예측 불가능한 버그가 발생할 수 있지않을까? -> 이를 동시성 문제라고 한다.
궁금해서 알아본 내용
멀티 스레드를 병렬적으로 실행하려면 멀티코어 환경은 필수적인가?
- 필수적이다. 싱글 코어 환경으로도 여러개의 멀티 스레드를 사용할 수 있지만 사실 스케줄링을 통해서 concurrency하게 실행되지만 사용자 눈에는 멀티 스레딩처럼 보인다. 멀티 코어 환경에서 스레드를 처리해야 진짜 병렬적 멀티 스레드 환경이 구성된다.
멀티 스레드 환경에서 CPU가 처리하는것은 PCB or TCB?
- 스레드가 CPU에서 실행되고 있을 때는 해당 스레드의 context를 나타내는 TCB(Thread Control Block)을 사용한다. 이를 통해 스레드 간 Context Switch를 할 때에도 context switch할 스레드간의 TCB로 전환된다!
3. 멀티 스레드의 장점
1. 응답성(Responsiveness)
- 여러 스레드를 통해 (멀티 코어 환경에서)병렬적으로 작업을 처리할 수 있기 때문에 빠른 응답을 줄 수 있다.
- I/O작업시 Blocking이 발생하지만 멀티스레드를 이용하여 Non-Blocking형태로 처리하여 I/O처리 작업이 끝날때 까지 기다리지 않고 다른 스레드를 통해 작업을 수행할 수 있다
2. 자원 공유(Resource sharing)
- 프로세스간 통신을 하기 위해서는 다른 프로세스의 자원에 접근할 수 없기 때문에 공유 메모리를 만들어서 통신해야했다(IPC). 하지만 멀티스레드는 한 프로세스 안에서 여러개의 스레드가 프로세스 자원을 공유하기 때문에 굳이 공유메모리를 사용하지 않고 자원을 쉽게 공유할 수 있다.
3. 경제성(Economy)
- 프로세스를 생성할 때 fork를 통해 메모리 공간을 복제하고 context switch를 할 경우 CPU를 초기화하고 switch한 프로세스 정보를 올려야 하기 때문에 프로세스간 context switch는 비효율적이다. 하지만 스레드는 메모리를 할당받을 필요없이 프로세스가 할당받은 메모리를 공유하고 각각 할당되는 stack, TID등 스레드 정보만 새로 올리면 되기 때문에 프로세스 context switch보다 비용이 저렴하다.
4. 확장성
멀티 코어 환경에서 멀티 스레드를 사용하면 병렬적 처리를 할수 있다. 즉 스레드의 수를 늘림으로써 시스템의 성능과 처리량을 향상시킬 수 있다.
그럼 스레드를 많이 사용하면 무조건 좋은거네??
이건 맞는 말이면서 틀린 말이다.
멀티 스레드의 장점 중 경제성에서는 프로세스 Context switch보다는 스레드의 Context switch를 하는 비용이 더 저렴하기 때문에 경제성 부분에서 좋다고 했다. 이 말은 맞는말이다. 하지만 스레드도 Context switch를 하려면 진행한 작업의 정보를 TCB에 저장하는 과정이 필요하다. 이처럼 일을 처리하는 CPU의 갯수는 변하지 않는데 스레드만 무작정 늘려버리면 괜히 바꾸는 시간만 더 들게된다. 이능 성능 저하로 이어질 수 있다.
두번째로 만약 프로그램이 CPU에서 처리하는 과정이 많은 프로그램이라면 괜히 나눠서 오버헤드를 늘릴 필요는 없다. 반대로 내가 실행하는 프로그램이 IO가 많은 프로그램이면 스레드를 늘려서 IO가 일어날 때 일부 스레드는 IO를 기다리고 일부 스레드는 일을 처리하도록 나누면 실행 속도는 개선될 수 있다. 하지만 이 경우에서도 스레드를 엄청 늘리면 이것 또한 안좋기 때문에 어디에서나 적당한게 좋다
4. User threads / Kernel threads
1. User threads
- 프로그래머가 라이브러리를 활용해서 구현한 스레드
- CPU의 코어들에 대해 직접 관리하지 못하는 스레드
2. Kernel threads
- 운영체제가 직접 관리하는 스레드
- CPU의 코어를 직접 제어할 수 있는 스레드
우리가 라이브러리를 사용해서 구현한 User threads는 OS랑 관련이 없기 때문에 CPU에서 처리가 되려면 Kernel threads와 연결되어 사용해야 한다. 이제 이 두개의 스레드 모드를 연결하는 방법에 대해 알아보자
5-1. Many to One Model
그림과 같이 여러개의 User thread가 하나의 단일 Kernel thread에 매핑된다. 커널 스레드 하나는 코어에 직접 붙어있고 여기에 나머지 유저 스레드들이 context switch를 하며 바꿔가면서 실행되는 모델이다. 커널 스레드의 개입 없이 context switch를 하기 때문에 밑의 One-to-One모델보다 switching이 빠르다.
이 모델이 가진 단점은 많은 유저스레드가 단 하나의 커널 스레드에 묶여 있기 때문에 유저스레드가 엄청 많아지면 커널 스레드 하나가 감당을 못한다. 그리고 하나의 kernel thread가 blocking IO를 만나게 되면 유저스레도 모두가 Blocking된다.
5-2. One to One Model
일대일 모델은 그림과 같이 유저 스레드와 커널 스레드가 1:1로 매핑된 모델이다. 그래서 하나의 스레드가 Blocking IO를 받으면 매핑된 유저 스레드는 블로킹되지만 다른 스레드들은 1:1 매핑이기 때문에 영향을 받지 않아 병렬적으로 처리가 가능하다. 하지만 여러 스레드들이 프로세스의 공통된 자원을 동시에 접근하기 때문에 race condition문제가 발생할 수 있다.
5-3. Many to Many Model
Many-to-One 모델과 One-to-One 모델의 단점을 해결한 모델이 바로 Many-to-Many 모델이다.
Many-to-One 모델에서의 단점중 하나의 커널 스레드가 Blocking IO를 만났을 때 다른 유저스레드가 전부 Blocking 되는 단점이 있다고 했는데 이번 Many-to-Many모델은 여러개의 커널스레드가 있기 때문에 하나가 만약 Blocking 된다고 해도 다른 스레드에서는 태스크를 처리할 수 있다.
Many-to-Many모델은 개발자가 필요한 만큼 스레드 생성을 제어할 수 있으며 커널스레드의 갯수는 유저 스레드의 갯수보다 적거나 같아야 한다.
5-4. Two-level Model
Many-to-Many 모델을 발전시킨 모델이 Two-level 모델이다.
일반적인 경우 Many-to-Many 모델을 사용하고 가벼운 프로그램이나 스레드가 다른 스레드에 영향을 미치지 않아야 할 때(계산 작업 > 여러 계산을 동시에 수행하는 경우 스레드간의 연산 결과가 다른 스레드의 연산 결과에 영향을 미치지 않아야 함.) 1:1매핑을 따로 사용한다.
CS 지식을 공부하고 기록하는 개인 공부 블로그입니다.
내용 중 틀린 부분 피드백 혹은 궁금한 점이 있으면 댓글로 남겨주시면 참고 및 답변 달아드리겠습니다🧐
'Computer Science > 운영체제' 카테고리의 다른 글
[OS/운영체제] CPU scheduling (0) | 2024.01.01 |
---|---|
[OS/운영체제] Implicit Threading / 암묵적 스레딩이란? (0) | 2023.12.31 |
[OS/운영체제] 동기 & 비동기 VS 블로킹 & 논블로킹 (1) | 2023.12.18 |
[OS/운영체제] IPC / Inter Process Communication (1) | 2023.12.18 |
[운영체제] Memory layout (0) | 2023.12.14 |