표준 스레드 라이브러리를 이용해서 스레드 구동하기

·2023년 12월 17일
0

GameServer

목록 보기
1/2
#include <thread>

void HelloThread()
{
	cout << "hello thread" << endl;
}

int main()
{
	std::thread t;
    t = std::thread(HelloThread);
    
    cout << "hello main" << endl;
}

에러 발생
-> main 함수가 스레드 보다 먼저 끝나는 경우가 있음
이럴 때는 join()를 사용해서 해당 스레드가 끝날 때 까지 main 스레드가 기다리도록 만들어야 함

그런데 데몬 프로세스와 같이 스레드 객체에서 실제 스레드가 분리된 경우도 있으므로 아래와 같이 주로 사용함

if (t.joinable()) // 실질적으로 연동된 thread가 있다면
	t.join();       // t 쓰레드가 종료될 때 까지 기다려줘

HelloThread() 내에 중단점을 걸고 확인 해 보면 아래와 같이 주 스레드(main thread)가 아닌 다른 스레드가 해당 함수 내부에 접근했음을 확인할 수 있음

thread 관련 자주 사용되는 함수

std::thread t;

// (1) hardware_concurrency()
// CPU 코 개수에 대한 힌트를 주는 함수, 경우에 따라 0을 리턴하기도 함
int32 count = t.hardware_concurrency(); // 노트북 기준 16 나옴

// (2) get_id()
// 스레드마다 부여되는 id (순차적으로 늘어나는 값은 아님)
// 스레드를 생성했다고 바로 부여되는 것은 아니고 해당 스레드에 함수를 호출하는 등
// 작업을 할 때 id가 부여됨
auto id = t.get_id();

// (3) detach()
// std::thread 객체에서 실제 스레드를 분리
// 리눅스의 데몬 프로세스와 비슷하며
// 해당 함수를 사용한 이후에는 생성 시 만든 t 객체로 관리 불가
t.detach();

// (4) join
// 실질적으로 연동된 thread가 있다면 해당 스레드가 종료될 때 까지 기다려줘
// 보통 mainThread에서 생성한 다른 thread가 끝날 때 까지 기다리는 데 사용함
if(t.joinable())
	t.join();

thread와 vector

void HelloThread2(int32 num)
{
	cout << num << endl;
}

int main()
{
	vector<std::thread> v;

	for (int32 i = 0; i < 10; i++)
	{
		// vector에 스레드를 생성해서 넣어주는데 바로 hellothread2 함수를 실행함
		// 해당 함수는 int32 인자를 받음 -> 이 경우 인자를 바로 옆에 , 찍고 넣어주면 됨
		// 함수 내부를 살펴보면 _Args&&... 과 같이 가변 인자 목록으로 되어있음
		// 즉, 인자를 여러 개 받는 함수인 경우 이어서 , 찍고 계속해서 쓰면 됨
		v.push_back(std::thread(HelloThread2, i));
	}

	for (int32 i = 0; i < 10; i++)
	{
		if (v[i].joinable())
			v[i].join();
	}
}

실행을 해 보면 아래와 같이 순차적으로 출력 되는 것은 아님

→ 동기화를 하지 않았기 때문

0개의 댓글