1. 스레드(Thread)
프로세스 내에서 실행되는 작은 실행 단위.
프로세스 내에서 생성되며 자원을 스레드 간 공유한다.
(코드, 데이터, 힙 메모리 등을 공유)
* 프로세스와 스레드의 차이
- 프로세스는 실행하고 있는 프로그램이다. 다른 프로그램과는 완전히 독립되어 있다.
동시에(병렬적으로) 실행된다.
- 스레드는 하나의 프로세스 내에서 생성된다. 스레드 간 메모리에 접근할 수 있다.
병렬적으로 사용하기 위해서는 동기화를 해야 한다.
2. 멀티 스레드(Multi-Thread)
여러 스레드를 병렬로 사용하여 작업을 수행하는 것.
각 CPU 코어가 각 스레드를 병렬적으로 처리한다.
ex) 쿼드 코어(코어 4개) CPU가 스레드 4개를 1:1 처리
각 스레드가 병렬적으로 명령을 처리할 수 있지만, 동일한 힙 메모리 영역을 사용하기 때문에 스레드들이 같은 값을 여러번 고칠 수도 있다.
3. 스레드 생성
#include <thread>
위의 헤더를 추가하여 스레드를 생성할 수 있다.
void HelloThread()
{
cout << "Hello Thread" << endl;
}
int main()
{
std::thread t(HelloThread);
cout << "Hello Main" << endl;
while (true)
{
}
}
기존의 main 함수를 실행하는 스레드가 있고, 우리가 생성해준 t 스레드(HelloThread 함수를 실행함)가 있다.
main 스레드(부모 스레드)가 종료되었을 때 t 스레드(자식 스레드)가 아직 실행 중이기 때문에 크래시가 발생한다.
따라서 t 스레드를 main 스레드보다 먼저 종료시키거나, main 스레드를 종료시키지 않아야 한다.
(무한 루프를 사용하여 main 스레드를 유지하는 방법을 사용했다)
만약 해당 스레드를 종료시키기를 원한다면 join 함수를 사용할 수 있다.
t.join();
(1) 매개변수 넘기기
void HelloThread(int i) { };
위처럼 t 스레드에서 실행되는 HelloThread 함수가 매개변수를 가질 때 스레드에 해당 매개변수도 같이 넘길 수 있는 문법도 있다.
std::thread t(HelloThread, 100);
(2) 스레드를 여러 개 만들기
void HelloThread(int i)
{
while (true)
{
cout << "Hello Thread" << i << endl;
}
}
int main()
{
vector<thread> threads;
for (int i = 0; i < 10; i++)
{
threads.push_back(thread(HelloThread, i));
}
cout << "Hello Main" << endl;
for (thread& t : threads)
t.join();
}
vector와 같은 컨테이너를 이용하여 여러 개의 스레드를 만들어 실행할 수 있다.
* 컨텍스트 스위칭(Context Switching)
스레드가 무작정 많다고 좋은 것이 아니다. 보통 스레드는 CPU의 코어 개수에 맞춰가는 것이 좋다.
스레드가 코어 개수보다 많아지면 각 코어에서 컨텍스트 스위칭을 통해 한 스레드가 다른 작업으로 스위칭하는 작업이 발생하는데, 이 때 비용이 많이 들게 된다.
(3) 주의 사항
각 스레드는 각자의 스택 영역을 가진다. 하지만 힙 영역과 데이터 영역을 공유하여 사용하기 때문에 주의하여야 한다.
'서버 프로그래밍 > 멀티 스레드' 카테고리의 다른 글
1-6. CAS(Compare And Swap), 스핀 락(Spin Lock) (0) | 2023.11.24 |
---|---|
1-5. 락 (Lock), 뮤텍스(mutex), RAII 패턴, lock_guard (0) | 2023.11.24 |
1-4. 공유 자원과 경쟁 조건 (0) | 2023.11.23 |
1-3. 캐시, CPU 파이프라인, 스레드 경쟁 조건 (1) | 2023.11.23 |
1-1. 게임 서버란? (0) | 2023.11.23 |