검색결과 리스트
__resumable에 해당되는 글 1건
- 2014.02.19 [C++] __resumable/__await
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"를 설치하면 이 기능을 테스트 해 볼 수 있다.
설치 후 프로젝트의 속성에서 "플랫폼 도구 집합"에서 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
C++ await
개인적인 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;
}
댓글