선물과 약속


135

나는 미래와 약속의 차이점을 혼동하고 있습니다.

분명히, 그들은 방법과 재료가 다르지만 실제 사용 사례는 무엇입니까?

그렇습니까? :

  • 비동기 작업을 관리 할 때 future를 사용하여 "미래의 가치"를 얻습니다.
  • 비동기 작업 일 때 약속을 반환 형식으로 사용하여 사용자가 약속에서 미래를 얻을 수 있도록합니다.

1
이 답변 에 이것 대해 조금 썼습니다 .
Kerrek SB

1
의 가능한 중복 수 std 무엇 : 약속?
Nicol Bolas

답변:


163

미래와 약속은 비동기 작업의 두 가지 측면입니다.

std::promise 비동기 작업의 "제작자 / 작성자"가 사용합니다.

std::future 비동기 작업의 "소비자 / 리더"에서 사용합니다.

이 두 개의 "인터페이스"로 분리 된 이유 는 "소비자 / 판독자"에서 "쓰기 / 설정"기능 을 숨기기 때문입니다.

auto promise = std::promise<std::string>();

auto producer = std::thread([&]
{
    promise.set_value("Hello World");
});

auto future = promise.get_future();

auto consumer = std::thread([&]
{
    std::cout << future.get();
});

producer.join();
consumer.join();

std :: promise를 사용하여 std :: async를 구현하는 하나의 (불완전한) 방법은 다음과 같습니다.

template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
    typedef decltype(func()) result_type;

    auto promise = std::promise<result_type>();
    auto future  = promise.get_future();

    std::thread(std::bind([=](std::promise<result_type>& promise)
    {
        try
        {
            promise.set_value(func()); // Note: Will not work with std::promise<void>. Needs some meta-template programming which is out of scope for this question.
        }
        catch(...)
        {
            promise.set_exception(std::current_exception());
        }
    }, std::move(promise))).detach();

    return std::move(future);
}

std::packaged_task어떤 도우미를 사용하면 (즉, 기본적으로 우리가 위에서하고있는 일을 수행합니다) std::promise더 완전하고 가능하면 더 빠른 다음을 수행 할 수 있습니다.

template<typename F>
auto async(F&& func) -> std::future<decltype(func())>
{
    auto task   = std::packaged_task<decltype(func())()>(std::forward<F>(func));
    auto future = task.get_future();

    std::thread(std::move(task)).detach();

    return std::move(future);
}

이것은 실제로 스레드가 끝날 때까지 실제로 블록을 막을 때 std::async반환 되는 위치와 약간 다릅니다 std::future.


3
@taras는 귀환 std::move(something)이 쓸모없고 (N) RVO도 아프다고 제안합니다 . 그의 편집을 되돌립니다.
polkovnikov.ph

Visual Studio 2015에서는 std :: cout << future.get (). c_str ();을 사용하십시오.
Damian

6
여전히 혼란스러워하는 사람들은 이 답변을 참조하십시오 .
kawing-chiu

2
그것은 일회성 생산자-소비자, 실제 생산자가 아닌 IMHO-소비자 패턴입니다.
Martin Meeser
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.