[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: 게임 서버"