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를 써요.

더 알아보기 (Learn more)

cppreference