Post List

2014년 12월 22일 월요일

Async

Async (Visual Studio 2013부터 사용가능)

비동기로 수행 가능한 task를 생성하고, 시스템이 관리하는 thread launcher(보통 thread pool)에게 실행을 위임합니다.
thread를 생성하면 System level의 실제 thread가 하나씩 만들어지지만, async task 하나당 thread가 하나씩 생성되지는 않는다. 시스템이 알아서 현재 thread상태를 보고 할당한다. 되도록이면 thread보다는 async를 사용하는 것을 추천한다.

1. Header 파일

#include <future>

2. 기본적인 사용방법

사용법은 thread와 거의 동일하다. 단 값을 읽어 올때는 .get()이라는 함수를 사용한다. async는 std::future<T> 형태의 type에 저장된다. future는 비동기 형태의 threadasync등의 data를 전달 받는 용도로 사용되는 객체이다. (참고로 data를 전달하는 것은promise객체를 사용한다.)

#include <iostream>
#include <future>

using std::cout;
using std::endl;
using std::async;
using std::future;

void f2(const int arg) { cout << "f2(" << arg << ")" << endl; }
void f3(const int arg, int*pResult) { cout << "f3(" << arg << ")" << endl; *pResult = arg; }
int f4(const int arg) { cout << "f4(" << arg << ")" << endl; return arg; }

void main()
{
    future<void> t1 = async([] { cout << "f1()" << endl; });  // lambda expression
    auto t2 = async(f2, 10);                                  // passing argument

    int result = -1;
    auto t3 = async(f3, 10, &result);                         // how to get the result
    cout << "[T3 : before get()] Result = " << result << endl;

    t1.get(); t2.get(); t3.get();
    cout << "[T3 : after get()] Result = " << result << endl;

    auto t4 = async(f4, 10);                                  // return value
    result = t4.get();

    cout << "[T4 : ager get()] Result = " << result << endl;
}

결과를 보면 .get()을 호출하기 전에는 async가 수행을 마쳤는지에 대해서 확신을 할 수가 없다. .get()을 호출한 뒤에는 확실히 수행을 마쳤다는 것을 확인 할 수 있다.


3. Launch Policy

async의 인자로 function, arguments 를 넣어서 사용하는 것이 기본적인 방법인데 그 앞에 launch policy를 넣어서 실행 할 수도 있다.용법은 thread와 거의 동일하다. 단 값을 읽어 올때는 .get()이라는 함수를 사용한다.

std::launch::async     : 정의한 후 바로 비동기로 실행한다.
std::launch::deferred  : .get() 호출 (future를 사용하여 결과를 대기) 할 때 실행한다. 

#include <iostream>
#include <future>
#include <chrono>

using std::cout;
using std::endl;
using std::async;
using std::future;
using std::this_thread::sleep_for;

using namespace std::chrono;

void main()
{
        int nCount = 0;

        future<void> F1 = async(std::launch::async, [&] {
               cout << "F1 : " << nCount << endl;
        });

        future<void> F2 = async(std::launch::deferred, [&] {
               cout << "F2 : " << nCount << endl;
        });

        ++nCount;
        sleep_for(milliseconds(500));

        ++nCount;
        F1.get();

        ++nCount;
        F2.get();
}

아래 결과를 보면 F1은 main thread가 sleep 할 때 실행했다는 것을 확인 할 수 있는데, F2는 .get()이 호출 되었을 때 실행됬다는 것을 알 수 있다.






참고 : MSDN http://msdn.microsoft.com/ko-kr/library/hh920535.aspx

댓글 없음:

댓글 쓰기