Post List

2014년 12월 22일 월요일

Thread

Thread (Visual Studio 2012부터 사용 가능)

이제까지 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

댓글 없음:

댓글 쓰기