小编TBB*_*Ble的帖子

std :: promise set_value和线程安全

我对线程安全方面的要求有点困惑std::promise::set_value().

标准说:

效果:以原子方式将值r存储在共享状态中并使该状态准备就绪

但是,它也说promise::set_value()只能用于设置一次值.如果多次调用,std::future_error则抛出a.因此,您只能设置一次承诺的值.

实际上,几乎每个教程,在线代码示例或实际用例都std::promise涉及两个线程之间的通信通道,其中一个线程调用std::future::get(),另一个线程调用std::promise::set_value().

我从来没有见过多个线程可能调用的用例std::promise::set_value(),即使他们这样做,除了一个std::future_error之外的所有线程都会引发异常.

那么为什么调用的标准命令std::promise::set_value()是原子的呢?std::promise::set_value()同时从多个线程调用的用例是什么?


编辑:

由于这里的最高投票答案并没有真正回答我的问题,我认为我所要求的不清楚.所以,澄清一下:我知道未来和承诺是什么以及它们如何运作.我的问题是,具体来说,为什么标准坚持认为std::promise::set_value()必须是原子的?这是一个更为微妙的问题,而不是"为什么呼叫promise::set_value()和呼叫之间不能有竞争future::get()"?

事实上,这里的许多答案(错误地)都会回答原因是因为如果std::promise::set_value()不是原子的,那么std::future::get()可能会导致竞争条件.但是这是错误的.

避免竞争条件的唯一要求是std::promise::set_value()必须具有与之发生的关系std::future::get()- 换句话说,必须保证在std::future::wait()返回时std::promise::set_value()已完成.

这与std::promise::set_value()原子本身是否完全正交.在使用条件变量的典型实现中,std::future::get()/wait()将等待条件变量.然后,std::promise::set_value()可以非原子地执行任何任意复杂的计算来设置实际值.然后它将通知共享条件变量(暗示具有释放语义的内存栅栏),std::future::get()并将唤醒并安全地读取结果.

因此,std::promise::set_value()本身并不需要原子来避免竞争条件 - 它只需要满足与之发生的关系std::future::get().

所以再一次,我的问题是:为什么 …

c++ multithreading language-lawyer c++11

21
推荐指数
2
解决办法
4084
查看次数

为什么C++显式实例化的模板方法不能覆盖虚方法?

为什么以下代码中的TemplateChild不起作用?我知道虚方法不能是模板,但为什么显式实例化模板方法不能覆盖虚方法?

#include <iostream>

class VirtBase
{
public:
    VirtBase() {};
    virtual ~VirtBase() {};

    virtual void method( int input ) = 0;
    virtual void method( float input ) = 0;
};

class RegularChild : public VirtBase
{
public:
    RegularChild() {};
    ~RegularChild() {};

    void method( int input ) {
        std::cout << "R" << input << std::endl;
    }
    void method( float input ) {
        std::cout << "R" << input << std::endl;
    }
};

class TemplateBounceChild : public VirtBase
{
public:
    TemplateBounceChild() {};
    ~TemplateBounceChild() {}; …
Run Code Online (Sandbox Code Playgroud)

c++ templates virtual-inheritance

6
推荐指数
2
解决办法
1117
查看次数