thread_promise

thread_promise (스레드 간 결과 전달을 위한 약속 객체)

이 페이지는 C++ 표준 라이브러리의 std::promise 클래스 템플릿에 대해 설명해요. std::promise는 나중에 std::future 객체를 통해 비동기적으로 결과를 얻을 수 있도록 값이나 예외를 저장하는 기능을 제공해요. promise 객체는 한 번만 사용할 수 있다는 점을 기억해야 해요.

출처: cppreference

본문

std::promise 클래스 템플릿은 나중에 std::promise 객체가 생성한 std::future 객체를 통해 비동기적으로 획득할 값이나 예외를 저장하는 기능을 제공해요. std::promise 객체는 한 번만 사용하도록 설계되었어요.

각 promise는 공유 상태(shared state)와 연결되어 있어요. 이 공유 상태에는 상태 정보와 아직 평가되지 않았거나 값(또는 void) 또는 예외로 평가된 결과가 포함돼요. promise는 공유 상태에 대해 다음 세 가지 작업을 할 수 있어요.

  • 준비 완료(make ready): promise가 결과나 예외를 공유 상태에 저장해요. 상태를 준비 완료로 표시하고 공유 상태에 연결된 future를 기다리는 모든 스레드를 깨워요.
  • 해제(release): promise가 공유 상태에 대한 참조를 포기해요. 마지막 참조였다면 공유 상태는 소멸돼요. std::async가 생성했고 아직 준비되지 않은 공유 상태가 아니라면 이 작업은 블록되지 않아요.
  • 포기(abandon): promise가 오류 코드 std::future_errc::broken_promise를 가진 std::future_error 예외를 저장하고, 공유 상태를 준비 완료로 만든 다음 해제해요.

promise는 promise-future 통신 채널의 "밀어내기(push)" 끝이에요. 공유 상태에 값을 저장하는 작업은 공유 상태를 기다리는 함수(예: std::future::get)의 성공적인 반환과 동기화돼요(std::memory_order에 정의된 대로). 같은 공유 상태에 대한 동시 접근은 그렇지 않으면 충돌할 수 있어요. 예를 들어 std::shared_future::get을 여러 번 호출하는 경우 모두 읽기 전용이거나 외부 동기화를 제공해야 해요.

멤버 함수

멤버 함수 설명
(constructor) promise 객체를 생성해요 (public member function)
(destructor) promise 객체를 소멸해요 (public member function)
operator= 공유 상태를 할당해요 (public member function)
swap 두 promise 객체를 교환해요 (public member function)

결과 가져오기

함수 설명
get_future 약속된 결과와 연결된 future를 반환해요 (public member function)

결과 설정하기

함수 설명
set_value 결과를 특정 값으로 설정해요 (public member function)
set_value_at_thread_exit 스레드 종료 시에만 알림을 전달하면서 결과를 특정 값으로 설정해요 (public member function)
set_exception 결과가 예외를 나타내도록 설정해요 (public member function)
set_exception_at_thread_exit 스레드 종료 시에만 알림을 전달하면서 결과가 예외를 나타내도록 설정해요 (public member function)

비멤버 함수

함수 설명
std::swap (std::promise) (C++11) std::swap 알고리즘을 특수화해요 (function template)

도우미 클래스

클래스 설명
std::uses_allocatorstd::promise (C++11) std::uses_allocator 타입 특성을 특수화해요 (class template specialization)

예제

이 예제는 promise<int>를 스레드 간 신호로 사용하는 방법을 보여줘요.

#include <chrono>
#include <future>
#include <iostream>
#include <numeric>
#include <thread>
#include <vector>
 
void accumulate(std::vector<int>::iterator first,
                std::vector<int>::iterator last,
                std::promise<int> accumulate_promise)
{
    int sum = std::accumulate(first, last, 0);
    accumulate_promise.set_value(sum); // Notify future
}

void do_work(std::promise<void> barrier)
{
    std::this_thread::sleep_for(std::chrono::seconds(1));
    barrier.set_value();
}
 
int main()
{
    // Demonstrate using promise<int> to transmit a result between threads.
    std::vector<int> numbers = {1, 2, 3, 4, 5, 6};
    std::promise<int> accumulate_promise;
    std::future<int> accumulate_future = accumulate_promise.get_future();
    std::thread work_thread(accumulate, numbers.begin(), numbers.end(),
                            std::move(accumulate_promise));

    // future::get() will wait until the future has a valid result and retrieves it.
    // Calling wait() before get() is not needed
    // accumulate_future.wait(); // wait for result
    std::cout << "result=" << accumulate_future.get() << '\n';
    work_thread.join(); // wait for thread completion
    
    // Demonstrate using promise<void> to signal state between threads.
    std::promise<void> barrier;
    std::future<void> barrier_future = barrier.get_future();
    std::thread new_work_thread(do_work, std::move(barrier));
    barrier_future.wait();
    new_work_thread.join();
}

출력:

result=21

더 알아보기 (Learn more)

cppreference