本文共 931 字,大约阅读时间需要 3 分钟。
原子操作如名字所述,其操作是不可分割的操作。在多线程中,原子操作因不可分割性,对认识数据同步有这重要的作用,而且原子操作可以使用互斥锁进行模拟。标准原子类型定义在<atomic>头文件中,或许c++标志库中原子库的实现就是通过互斥锁模拟的,我们可以通过其方法is_lock_free()检测是否该类型内部是通过使用锁模拟的,若返回false则表示该原子类型是库或是编译器内部使用一个锁实现的。
<atomic>头文件中,有一个特殊的原子类型atomic_flag,该类型除了清除clear()和查询test_and_set()函数,不存在其他的操作,在使用前必须被初始化为ATOMIC_FLAG_INIT,而这个标志位相当于false状态,也就是说初始化总是为false; atomic_flag atm_flg = ATOMIC_FLAG_INIT; flg.clear();----清除标志 flg.test_and_set();----按照默认的内存顺序设置标志,并检索旧值。程序如下:
其他的原子类型是可以通过模板atomic<>特化得到,eg:atomic<bool>b;定义一个bool类型的原子对象。 这与前面的atomic_flag存在差异,更接近于平常的bool类型数据,有着存储、加载、设置等操作。其他类型的atomic<>特化也有着相似的操作。具体操作函数如下图(图摘自c++ concurrency in action): 其中exchange(nwVal)直接将对象存储的值替换为新值,并返回以前存储的值。 compare_exchange_strong(expVal,val)对比交换,若期望值与存储的值不同,则将期望的值更新为存储的值,返回false;若相同,存储提供的val值,返回true。 而compare_exchange_weak(expVal,val)不同的是,即使期望值和存储的值相同,也可能存储操作出现错误,从而返回false,造成这种情况的原因是时间。所以基本会使用一个循环进行检测。 注意:调用fetch_add()/fetch_sub()等操作,对象可以进行加/减等运算,但是返回的是原始值。 如下程序所示:转载地址:http://qsjmb.baihongyu.com/