본문으로 바로가기

C++20) Coroutine ( 코루틴 ) - 2

category C++/Modern 2020. 8. 21. 18:26

Coroutine 상태가 할당되면, 해당 할당이 힙에서 발생할 수도 있습니다.

( 힙에 발생해야한다고 생각해야하지만, 컴파일러가 최적화 할 수도 있습니다. )

 

만약 힙에서 발생하고, 우리가 만든 promise_type이 get_return_object_on_allocation_failure 을 선언해놨다면,

non-throwing 버전의 new 연산자가 검색됩니다.

만약 Coroutine 할당에 실패하면, 즉시 예외가 발생하지 않습니다. 대신

컴파일러는 호출자쪽의 get_return_object_on_allocation_failure 함수를 호출합니다.

그러므로 다음과 같은 정적 멤버 함수를 promise_type에 선언 및 정의 합니다.

 

 

우리의 resumable 은 default 생성된 coroutine_handle 을 지원하지 않기 때문에 ( from_promise ) 예외처리를 해야한다.

-> 우리는 handle을 사용하기전에, handle 할당이 실패했는지도 검사하지 않기 때문에.

 

우리가 작성한 func() 함수에 마우스를 가져다 대면, operator new 가 연결됨을 볼 수 있습니다. 

우리가 promise_type::operator new 를 재정의 하고, 할당 실패를 알려준다면, bad_alloc을 던집니다.

 

우리가 재정의한 new 연산자가, 할당에 실패한다면 get_return_object_on_allocation_failure 함수에 진입하게 됩니다.

 

코루틴의 반환 ( co_return )

 

앞에서 작성한 것과 같이, co_return 을 통하여 Coroutine에서 값을 반환할 수 있습니다. 하지만 이를 위해서 개발자가 일부 추가 지원을 해야 합니다.

 

일단, co_return 키워드가 발생할 때 co_return이 어떻게 작동하는지를 컴파일러 생성 코드 종류로 파악하면 다음과같다.

 

1. 값의 반환이 없을 때 

 

이미 우리의 promise_type은 return_void를 작성해놨으므로, 더 이상 작성할 필요가 없습니다.

 

2. 값의 반환이 있을 때

 

우리의 promise_type은 return_value가 없으므로, 작성해야 합니다.

 

문자열을 반환받을 것이므로, const char* type의 값을 받아내도록 했습니다.

[ 참고 : return_void 와 return_value 둘 다 정의할 순 없습니다. ]

 

실제로, coroutine_handle이 promise에 대한 정보를 가지고 있으므로, 이를 통해 값을 얻어냅니다.

이제 resumable 과 func 그리고 main을 수정합니다.

 

 

 

 

이렇게 하면 코루틴내에서 값을 반환할 수 있으며, coroutine_handle 의 promise 접근을 통해 값을 받아낼 수 있습니다.

 

[참고]

호출 스택을 통해 Coroutine의 초기화를 확인할 수 있으며

Coroutine_handle을 통해 suspend point를 확인할 수 있습니다.

 

 

'C++ > Modern' 카테고리의 다른 글

C++20) Concepts ( 콘셉트, 개념 ) - 1  (0) 2020.11.25
C++20) Coroutine ( 코루틴 ) - 3  (0) 2020.08.23
C++20) Coroutine ( 코루틴 ) - 1  (0) 2020.08.20
C++20) Designated Initializer ( 지정된 초기화 )  (0) 2020.08.19
C++17) std::variant  (0) 2019.02.28