C++의 차기 표준이 될 C++17에 들어갈 후보 중 비동기 프로그래밍과 관련된 ConcurrenctTS에는 MS에서 제의한 기능 중 __resumable/__await가 있다.

최신의 C# 언어를 알고 있다면 아마 __resumable/__await가 무엇인지 대충 감을 잡을 것이다.

__resumable/__await은 C#으로 친다면 async/await에 해당된다.

 

__resumable 지시어를 사용한 함수 a에서 __await 지시어로 작업을 비동기로 처리하면서 작업이 끝날 때까지 대기하지 않고 함수 a를 호출한 곳으로 제어를 넘긴 후 비동기 작업이 끝나면 다시 함수 a로 제어권이 넘어가서 __await 이후에 남은 작업을 처리한다.

 

현재 VC에서는 Visual Studio 2013의 "Visual C++ Compiler November 2013 CTP"를 설치하면 이 기능을 테스트 해 볼 수 있다.

다운로드: http://blogs.msdn.com/b/vcblog/archive/2013/11/18/announcing-the-visual-c-compiler-november-2013-ctp.aspx

 

설치 후 프로젝트의 속성에서 "플랫폼 도구 집합"에서 CTP용 컴파일러를 선택한다.

 

아래 예제를 보면 대충 어떤 기능이고 어떻게 사용하는지 알 수 있을 것이다.

 

(코드는 http://www.rsdn.ru/forum/cpp/5366761.1 것을 참고하였다)

 

VC의 경우 C++의 스레드 기능은 VC 자체 라이브러리인 ConcurrencyRuntime 위에서 실행되므로 __resumable/__await도 ConcurrencyRuntime의 API를 사용하여 구현 되어 있다.

위와 비슷한 것을 ConcurrencyRuntime API를 사용하면 아래와 같다.

 

 

좀 더 자세한 설명은 아래를 참고 하면 좋을 것이다.

Asynchronous programming in C++ using resumable functions and await

http://blogs.msdn.com/b/vcblog/archive/2013/12/20/asynchronous-programming-in-c-using-resumable-functions-and-await.aspx

C++ await

http://view.officeapps.live.com/op/view.aspx?src=http%3a%2f%2fvideo.ch9.ms%2fsessions%2fgonat%2f2013%2fGN13BrewisAwait.pptx

 

개인적인 C++17 이전에 새 버전의 VC에서는 정식으로 __resumable/__await이 들어가지 않을까 생각한다.

 

< 예제 1 >

#include <iostream>

#include <thread>

#include <ppltasks.h>

#include <pplawait.h>



concurrency::task<int> foo(int a) __resumable

{

std::cout << "foo 시작" << std::endl;


auto sum = a;

std::cout << "foo __await 시작" << std::endl;

sum += __await concurrency::create_task([] { 

std::cout << "foo 스레드ID: " << std::this_thread::get_id() << std::endl;

::Sleep(3000); 

return 20; 

});

std::cout << "foo __await 완료" << std::endl;


return sum;

}



int main()

{

std::cout << "main 시작. 스레드ID: " << std::this_thread::get_id() << std::endl;


std::cout << "foo 호출 전" << std::endl;

auto&& t = foo(1);

std::cout << "foo 호출 후" << std::endl;


std::cout << "foo 결과 대기" << std::endl;

std::cout << t.get() << '\n';

std::cout << "foo 결과 받음" << std::endl;


return 0;

}


< 예제 2>

#include <iostream>

#include <thread>

#include <chrono>


#include <ppltasks.h>

#include <pplawait.h>



int __suspendable_foo(int a)

{

std::cout << "__suspendable_foo" << std::endl;


auto sum = a;


std::cout << "await_task 시작" << std::endl;

sum += concurrency::details::await_task<int>(concurrency::create_task([] {

std::cout << "task 스레드ID: " << std::this_thread::get_id() << std::endl;

std::this_thread::sleep_for(std::chrono::milliseconds(2));

return 20;

}));


std::cout << "await_task 완료" << std::endl;


return sum;

}


concurrency::task <int> __create_resumable_foo()

{

std::cout << "__create_resumable_foo" << std::endl;


return concurrency::details::create_resumable_context<concurrency::task<int>>([]

{

return __suspendable_foo(11);

});

}



int main()

{

std::cout << "main 시작. 스레드ID: " << std::this_thread::get_id() << std::endl;


std::cout << "__create_resumable_foo 호출 전" << std::endl;

auto&& t = __create_resumable_foo();

std::cout << "__create_resumable_foo 호출 후" << std::endl;


std::cout << t.get() << std::endl;


std::cout << "main 끝" << std::endl;

return 0;

}



신고
by 흥배 2014.02.19 08:00
| 1 |

티스토리 툴바