5.2.7 原子操作的释放函数

5.2.7 原子操作的释放函数

直到现在,我都还没有去描述成员函数对原子类型操作的形式。但是,在不同的原子类型中 也有等价的非成员函数存在。大多数非成员函数的命名与对应成员函数有关,但是需 要“atomic_”作为前缀(比如,std::atomic_load() )。这些函数都会被不同的原子类型所重载。 在指定一个内存序列标签时,他们会分成两种:一种没有标签,另一种将“_explicit”作为后缀,并且需要一个额外的参数,或将内存顺序作为标签,亦或只有标签(例如,std::atomic_store(&atomic_var, new_value)std::atomic_store_explicit(&atomic_var, ne w_value, std::memory_order_release )。不过,原子对象被成员函数隐式引用,所有释放函数都 持有一个指向原子对象的指针(作为第一个参数)。

例如,std::atomic_is_lock_free()只有一种类型(虽然会被其他类型所重载),并且对于同一个对象a,  std::atomic_is_lock_free(&a) 返回值与a.is_lock_free()相同。同样的,std::atomic_load(&a)a.load()的作用一样,但需要注意的是,a.load(std::memory_order_acquire)等价的操作是 std::atomic_load_explicit(&a, std::memory_order_acquire)

释放函数的设计是为了要与C语言兼容,在C中只能使用指针,而不能使用引用。例如, compare_exchange_weak()compare_exchange_strong()成员函数的第一个参数(期望值)是一个引用,而 std::atomic_compare_exchange_weak() (第一个参数是指向对象的指针)的第二个 参数是一个指针。 std::atomic_compare_exchange_weak_explicit() 也需要指定成功和失败的内 存序列,而“比较/交换”成员函数都有一个单内存序列形式(默认是std::memory_order_seq_cst ),重载函数可以分别获取成功和失败内存序列。

std::atomic_flag 的操作是“反潮流”的,在那些操作中它们“标志”的名称为: std::atomic_flag_test_and_set()std::atomic_flag_clear() ,但是以“_explicit”为后缀 的额外操作也能够指定内存顺序:std::atomic_flag_test_and_set_explicit() 和  std::atomic_flag_clear_explicit()

C++标准库也对在一个原子类型中的 std::shared_ptr<> 智能指针类型提供释放函数。这打破了“只有原子类型,才能提供原子操作”的原则,这里std::shared_ptr<> 肯定不是原子类型。 但是,C++标准委员会感觉对此提供额外的函数是很重要的。可使用的原子操作有:load,  store, exchangecompare/exchange,这些操作重载了标准原子类型的操作,并且获取一 个std::shared_ptr<>* 作为第一个参数:

std::shared_ptr<my_data> p;

void process_global_data()
{
    std::shared_ptr<my_data> local = std::atomic_load(&p);
    process_data(local);
}

void update_global_data()
{
    std::shared_ptr<my_data> local(new my_data);
    std::atomic_store(&p, local);
}

作为和原子操作一同使用的其他类型,也提供“_explicit”变量,允许你指定所需的内存顺序, 并且  std::atomic_is_lock_free() 函数可以用来确定实现是否使用锁,来保证原子性。

如之前的描述,标准原子类型不仅仅是为了避免数据竞争所造成的未定义操作,它们还允许 用户对不同线程上的操作进行强制排序。这种强制排序是数据保护和同步操作的基础,例 如,std::mutexstd::future<> 。所以,让我继续了解本章的真实意义:内存模型在并发方面的细节,如何使用原子操作同步数据和强制排序

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引入一个依赖后,启动springboot报错:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultValidator' defined in class path resource [org/springframework/boot/autoconfigure/validation/ValidationAutoConfiguration.class]: Invocation of init method failed; nested exception is java.lang.AbstractMethodError: org.hibernate.validator.engine.ConfigurationImpl.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider; at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1796) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:595) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:893) ~[spring-beans-5.2.7.RELEASE.jar:5.2.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:879) ~[spring-context-5.2.7.RELEASE.jar:5.2.7.RELEASE]
06-08

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值