【问题标题】:Is std::promise<T> thread-safe?std::promise<T> 是线程安全的吗?
【发布时间】:2017-03-01 14:30:45
【问题描述】:

std::mutex 那样将std::promise&lt;T&gt; 变成mutable 是否安全,还是取决于T?如:

using Data = std::tuple<bool, int, int>;

struct X {

    std::future<Data> prepare() const {
        return m_promise.get_future();
    }

    void asyncHandler(int a, int b) const {
        m_promise.set_value({true, a, b});
    }

    void cancel() const {
        m_promise.set_value({false, 0, 0});
    }

    mutable std::promise<Data> m_promise;  // Is this safe?
};


void performAsyncOp(const X& x) {
     std::future<Data> fut = x.prepare();
     dispatch(x);
     std::future_status result = fut.wait_for(std::chrono::milliseconds(150));
     if (result == std::future_status::timeout) {
         x.cancel();
     }

     handleResult(fut.get());
}

【问题讨论】:

  • 事实证明,由于期货不可重置,这种模式无论如何都被打破了。我原以为 future.get() 会重置它,但事实并非如此。我真的很难看到所有这些承诺/未来的东西的意义。

标签: c++ c++11 asynchronous promise


【解决方案1】:

让我们详细了解一下 API:

// retrieving the result
future<R> get_future();

// setting the result
void set_value(see below);
void set_exception(exception_ptr p);

// setting the result with deferred notification
void set_value_at_thread_exit(see below);
void set_exception_at_thread_exit(exception_ptr p);

没有一个方法被标记为const,所以我们不能从这个推断出任何关于常量的知识。但是,该标准要求以下方法的线程安全(参见33.6.6.2):set_­valueset_­exceptionset_­value_­at_­thread_­exitset_­exception_­at_­thread_­exit

这使得get_future 未指定线程安全性。但是,get_future 会在多次调用时引发异常,参见33.6.6.14.1。所以从多个线程调用get_future 从实际的角度来看并没有什么意义。

据我所知,同时调用get_future 和任何set 方法和get_future(无论它是否会抛出)时都无法保证线程安全。

【讨论】:

    猜你喜欢
    • 2018-01-19
    • 2018-03-31
    • 1970-01-01
    • 2014-05-23
    • 2017-12-23
    • 2017-05-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多