std::suspend_always
std::suspend_always (항상 일시 중단하는 awaiter)
코루틴이 항상 일시 중단(suspend)되도록 하는 간단한 awaiter 타입이에요. co_await std::suspend_always{}를 쓰면 awaiter가 항상 현재 코루틴을 일시 중단해요. C++20부터 있어요.
출처: cppreference
본문
<coroutine> 헤더에 정의돼 있고, 코루틴을 항상 일시 중단시키는 awaiter예요. 특수화 가능한(open) awaiter 타입으로, co_await 표현식에서 awaiter로 사용되면 항상 코루틴을 일시 중단해요.
struct suspend_always
{
constexpr bool await_ready() const noexcept;
constexpr void await_suspend( std::coroutine_handle<> ) const noexcept;
constexpr void await_resume() const noexcept;
};
await_ready():false를 돌려줘요. 즉 코루틴은 항상 일시 중단되어야 한다고 알려줘요.await_suspend(...): 일시 중단 후 수행할 동작. 특별한 일 없이 반환해요.await_resume(): 일시 중단에서 재개될 때의 반환 값. 아무것도 반환하지 않아요(void).
이 멤버들이 모두 constexpr이므로 co_await를 상수 식 문맥에서도 사용할 수 있어요.
일반적으로 코루틴의 promise 타입 안에서 co_await std::suspend_always{} 같은 형태로 쓰여서, 매번 코루틴을 멈추고 제어권을 호출자에게 돌려주는 역할을 해요. 다음 세그먼트 실행을 외부 스케줄러나 이벤트 루프에 맡기는 코루틴 모델에서 자주 사용돼요.
예제를 보면요.
#include <coroutine>
#include <iostream>
struct task
{
struct promise_type
{
task get_return_object() { return {}; }
std::suspend_always initial_suspend() { return {}; } // 시작 시 항상 중단
std::suspend_always final_suspend() noexcept { return {}; }
void return_void() {}
void unhandled_exception() {}
};
};
int main()
{
// 이 코루틴은 initial_suspend에서 항상 일시 중단되므로
// 본문은 호출 직후 실행되지 않아요.
std::cout << "main\n";
}
이렇게 std::suspend_always는 "항상 멈춘다"는 명확한 의미를 가진 가장 기본적인 awaiter예요. 반대로 항상 재개 계속하기 위해서는 std::suspend_never를 써요.