[Server Programming/cpp] thread

c++ 11부터 thread 사용 가능. 해당 모던 방식은 Linux/Win 플랫폼에서 모두 사용이 가능하다. *IOCP는 Win의 대표적인 메커니즘으로 Linux에선 사용이 불능

#include <iostream>
#include <thread>
using namespace std;

void HelloWorld() {
	cout << "Hello World" << endl;
}

int main()
{
	thread t1;
	t1 = thread(HelloWorld);
	return 0;
}	

위 코드를 실행시키면 에러가 뜬다. t1 동작 중에 메인 스레드가 먼저 종료되기 때문이다.

...
int main()
{
	thread t1;
	t1 = thread(HelloWorld);
	t1.join() //t1 스레드가 끝날때까지 대기
	return 0;
}	

위처럼 수정해보면 에러가 뜨지 않는다.

*cout은 무거운 실행 방식. os커널에 요청하는 system call을 사용하기 때문

thread 다양한 메소드

  • t.join()
  • t.joinable() // bool반환으로 thread가 join이 가능한 상태인지 판단
  • t.hardware_concurrency() // 실질적으로 구동가능한 하드웨어 스레드의 개수
  • t.getid() // 스레드의 id 생성자등 초기화하지 않은 선언 상태라면 0을 반환
  • t.detach() // thread 객체에서 실제 스레드를 분리 (데몬 스레드와 비슷하게 구현할 수 있다.)

예시

void HelloWorld_Two(int32 i) {
	cout << i << endl;
}

int main()
{
	thread t1;
	auto id1 = t1.get_id();
	t1 = thread(HelloWorld_Two,5);
	auto id2 = t1.get_id();
	auto hc = t1.hardware_concurrency();
	if(t1.joinable())
		t1.join();
	cout << id1 << endl;
	cout << id2 << endl;
	cout << hc << endl;
	
	return 0;
}	
5
0
4720
8

예시2

int main()
{
	vector<thread> vec;
	for (int32 i = 0; i < 10; i++)
	{
		vec.push_back(thread(HelloWorld_Two, i));
	}
	for (int32 i = 0; i < 10; i++)
	{
		if (vec[i].joinable())
		{
			vec[i].join();
		}
	}
	return 0;
}	
0
5
48
2
3

1
6
9
7

음 endl이 적용되지 않고 출력이 나오기도 하고 순서가 보장되지않는다.

각 스레드는 다른 스레드의 상태를 모르기 때문에 각자 행동을 하게되기에 이런 결과를 갖게된다.

출처

인프런 Rookiss, "[C++과 언리얼로 만드는 MMORPG 게임 개발 시리즈] Part4: 게임 서버"