여러 프로세스(메모리에 적재되어 실제로 실행 중인 프로그램)를 CPU 코어가 연산을 수행
이 프로세스들을 짧은 시간 안에 왔다갔다하며 수행하기 때문에 마치 동시에 연산을 수행하는 것처럼 보임
C++의 cout
과 같은 시스템콜은 프로그램이 운영체제의 커널에게 요청하는 작업 (프로그램이 직접 출력할 수 없고 운영체제가 대신 함)
윈도우, 리눅스 등 다양한 환경에서 동작할 수 있는 system call 함수를 사용하자 (윈도우 한정인 system call을 사용한다면 리눅스에서는 구동되지 않음)
#include "pch.h"
#include <iostream>
#include "CorePch.h"
#include <thread>
void HelloThread()
{
cout << "Hello Thread" << endl;
}
int main()
{
std::thread t(HelloThread); // HelloThread를 실행하는 t라는 이름의 스레드 생성
cout << "Hello Main" << endl;
}
main 함수에서 단순히 HelloThread를 호출한다면 그대로 메인 스레드에서 실행되지만, 스레드 t를 생성하면 메인스레드와 스레드t가 병렬적으로 실행된다.
스레드 t를 메인스레드가 관리하고 있는데 메인스레드가 먼저 종료되면 에러가 발생한다.
int main()
{
std::thread t(HelloThread); // HelloThread를 실행하는 t라는 이름의 스레드 생성
cout << "Hello Main" << endl;
t.join(); // t가 끝날 때까지 기다림 (t는 HelloThread를 모두 실행하면 종료)
}
이렇게 스레드 t가 종료될 때까지 기다리면 실행시 에러가 발생하지 않는 것을 볼 수 있다.
hardware_concurrency()
: CPU 코어 개수, 즉 실행할 수 있는 프로세스 개수
get_id()
: 스레드의 고유 id
detach()
: 스레드와의 연결을 끊음. 즉 std::thread객체에서 실제 스레드를 분리
joinable()
: 실제로 스레드가 존재하는지 핀딘
join()
: 스레드가 끝날 때까지 기다림
int main()
{
std::thread t; // 스레드 변수만 생성
auto id1 = t.get_id(); // 스레드 변수만 존재하고 실제로 스레드가 존재하지 않기 때문에 0을 리턴
t = std::thread(HelloThread); // 스레드 생성
auto id2= t.get_id(); // 유효한 id 리턴
int32 count = t.hardware_concurrency();// CPU 코어 개수, 즉 실행할 수 있는 프로세스 개수
if (t.joinable())
{
t.join();
}
cout << "Hello Main" << endl;
}
스레드 생성 시 함수의 인자를 함께 넘길 수 있다.
void HelloThread_2(int32 num)
{
cout << num << endl;
}
int main()
{
vector<std::thread> v;
for (int32 i = 0; i < 10; i++)
{
v.push_back(std::thread(HelloThread_2, i));
}
for (int32 i = 0; i < 10; i++)
{
if (v[i].joinable())
{
v[i].join();
}
}
cout << "Hello Main" << endl;
}
실행 결과
0, 1, 2, 3, 4, ... 순서대로 숫자가 호출되지 않는 이유는 스레드 생성의 순서는 정해져 있지만 생성된 스레드들은 병렬적으로 동작하기 때문이다.