이제까지 thread 관련 기능은 각 platform 마다 달라서, 한 개의 code를 여러 platform에서 사용할려면 thread 부분은 따로 구현해야만 했다. 하지만 이제는 thread가 C++ 표준규격으로 정의되어서 platform에 상관없이 같은 code로 구현이 가능해졌다.
1. Header 파일
#include <thread> |
2. 정의 방법
// 생성과 동시에 실행 std::thread t1([] { std::chrono::milliseconds tick(500); for (int i = 0; i < 5; i++) { std::cout << "Thread1[" << std::this_thread::get_id() << "] : " << i << std::endl; std::this_thread::sleep_for(tick); } }); // 생성 후 특정시점에 실행 std::thread t2; t2 =std::thread([] { std::chrono::seconds tick(1); auto StartTime = std::chrono::system_clock::now(); for (int i = 0; i < 5; i++) { std::cout << "Thread2[" << std::this_thread::get_id() << "] : " << i << std::endl; std::this_thread::sleep_until(StartTime + tick * i); } }); // Parameter 추가 std::thread t3 = std::thread([](int nParam) { for (int i = 0; i < 5; i++) std::cout << "Thread3[" << std::this_thread::get_id() << "] : " << nParam << std::endl; }, 4); |
3. 일시중지, 양보
- 일시중지 : sleep_for (일정 시간 동안 대기), sleep_until (특정 시점까지 대기)
- 양보 : yield(); : 자신의 활동을 잠시 멈추고 다른 thread에게 양보한다.
std::chrono::milliseconds tick(500); std::this_thread::sleep_for(tick);
std::chrono::seconds tick(1);
auto StartTime = std::chrono::system_clock::now();
std::this_thread::sleep_until(StartTime + tick * 10);
std::this_thread::yield();
|
4. thread 식별하기
std::thread t1([] { // Thread 안 std::cout << std::this_thread::get_id(); });
// Thread 밖
auto id = t1.get_id(); |
5. thread 종료까지 대기 및 thread 분리
std::thread t1([] {}); t1.join(); // t1 종료될때까지 대기. 이후 t1.get_id()는 오류 std::thread t2([] {}); t2.detach(); // t2 는 이제부터 관리하지 않음. 모든 t2. 으로의 제어가 불가능 |
6. thread swap : thread object 끼리 thread를 교환
#include <iostream>
#include <thread>
#include <mutex>
#include <chrono>
using std::cout;
using std::endl;
using std::thread;
using std::mutex;
using std::this_thread::get_id;
using std::this_thread::sleep_for;
using std::swap;
using namespace std::chrono;
void main()
{
mutex m;
int nThread1Cnt = 0;
int nThread2Cnt = 0;
thread T1 = thread([&]()
{
for (int i = 0; i < 10; ++i)
{
sleep_for(milliseconds(100));
++nThread1Cnt;
m.lock();
cout << nThread1Cnt << " : [T1] this, T1 ID : " << get_id() << " , " << T1.get_id() << endl;
m.unlock();
}
});
thread T2 = thread([&]()
{
for (int i = 0; i < 10; ++i)
{
sleep_for(milliseconds(200));
++nThread2Cnt;
m.lock();
cout << nThread2Cnt << " : [T2] this, T2 ID : " << get_id() << " , " << T2.get_id() << endl;
m.unlock();
}
});
while (nThread2Cnt < 3 &&
nThread1Cnt < 3) {}
m.lock();
cout << "swap(T1, T2);" << endl;
swap(T1, T2);
m.unlock();
while (nThread2Cnt < 9 &&
nThread1Cnt < 9) {}
m.lock();
cout << "T1.swap(T2);" << endl;
T1.swap(T2);
m.unlock();
T1.join();
T2.join();
}
|
T1, T2의 id가 바뀌면서 동작하는 것을 확인 할 수 있다.
6. thread_local : 각 thread 별로 고유 stack에 data 저장
#include <iostream>
#include <thread>
using std::cout;
using std::endl;
using std::thread;
using std::this_thread::get_id;
thread_local int nCount = 0;
void Test(int p_nNum)
{
for (int i = 0; i < p_nNum; ++i)
++nCount;
cout << "Thread ID [" << get_id() << "] : nCount = " << nCount << endl;
}
void main()
{
thread T1, T2,
T3;
T1 = thread(Test, 10);
T2 = thread(Test, 20);
T3 = thread(Test, 30);
T1.join();
T2.join();
T3.join();
}
|
nCount를 총 60번 ++ 시켰는데 그 결과를 보면 각 thread 별로 다른 값을 가지는 것을 확인 할 수 있다.
참고자료 : MSDN http://msdn.microsoft.com/ko-kr/library/vstudio/hh920526(v=vs.110).aspx
댓글 없음:
댓글 쓰기