15.1.3  原子模板的常规操作

15.1.3 原子模板的常规操作

头文件<atomic>提供了10个常规操作函数。其原型及意义分别如下:

978-7-111-51399-5-Chapter15-2.jpg

该函数用于判断std::atomic对象是否具备lock-free特性。如果某个对象满足lock-free特性,那么在多个线程访问该对象时不会导致线程阻塞。

978-7-111-51399-5-Chapter15-3.jpg

该函数用于初始化原子对象。val指定原子对象的初始值。若对一个已初始化的原子对象再次调用atomic_init(),则会导致未定义行为。若想修改原子对象的值,则应使用std::atomic_store()。

978-7-111-51399-5-Chapter15-4.jpg

该函数用于修改原子对象的值。该函数相当于std::atomic对象的store或者operator=()成员函数,若需要显式指定内存序,则应使用atomic_store_explicit。

978-7-111-51399-5-Chapter15-5.jpg

该函数用于修改原子对象的值。该函数相当于std::atomic对象的store或者operator=()成员函数,memory_order指定了内存序,其可取的参数为:

978-7-111-51399-5-Chapter15-6.jpg

978-7-111-51399-5-Chapter15-7.jpg

该函数用于读取被封装的值,默认的内存序为memory_order_seq_cst。该函数与std::atom-ic对象的atomic::load()成员函数等效。

978-7-111-51399-5-Chapter15-8.jpg

该函数用于读取被封装的值。参数sync设置了内存序,可能的取值如下:

978-7-111-51399-5-Chapter15-9.jpg

978-7-111-51399-5-Chapter15-10.jpg

该函数用于读取并修改被封装的值,exchange会用val指定的值替换掉之前该原子对象封装的值,并返回之前该原子对象封装的值,整个过程具有原子性(因此exchange操作也被称为read-modify-write操作)。

978-7-111-51399-5-Chapter15-11.jpg

该函数用于读取并修改被封装的值,exchange会用val指定的值替换掉之前该原子对象封装的值,并返回之前该原子对象封装的值,整个过程具有原子性(因此exchange操作也被称为read-modify-write操作)。

978-7-111-51399-5-Chapter15-12.jpg

该函数用于比较并交换被封装的值与参数第二个参数所指定的值是否相等,若相等,则用val替换原子对象的旧值;若不相等,则用原子对象的旧值替换第二个参数,因此调用该函数之后,如果被该原子对象封装的值与第二个参数所指定的值不相等,第二个参数中的内容就是原子对象的旧值。

该函数通常用于读取原子对象封装的值,若比较结果为true(即原子对象的值等于第二个参数),则替换原子对象的旧值,但整个操作是原子性的,即在某个线程读取和修改该原子对象时,其他线程不能读取和修改该原子对象。

注意

该函数直接比较原子对象所封装的值与第二个参数的内容。某些情况下,对象的比较操作在使用operator==()判断时相等,atomic_compare_exchange_weak判断时却可能失败,因为对象底层的物理内容中可能存在“位对齐”或其他逻辑表示“相同”但表示不同的值(比如true和2或3,它们在逻辑上都表示“真”,但其表示并不相同)。

978-7-111-51399-5-Chapter15-13.jpg

该函数用于比较并交换被封装的值(strong)与第二个参数所指定的值是否相等,若相等,则用val替换原子对象的旧值;若不相等,则用原子对象的旧值替换第二个参数,因此调用该函数之后,如果被该原子对象封装的值与第二个参数所指定的值不相等,第二个参数中的内容就是原子对象的旧值。

该函数通常会读取原子对象封装的值,若比较为结果true(即原子对象的值等于第二个参数值),则替换原子对象的旧值,但整个操作是原子性的。在某个线程读取和修改该原子对象时,另外的线程不能读取和修改该原子对象。

注意:该函数直接比较原子对象所封装的值与第二个参数的物理内容,所以在某些情况下,对象的比较操作在使用operator==()判断时相等,但compare_exchange_weak判断时却可能失败,因为对象底层的物理内容中可能存在位对齐或其他逻辑表示相同但是物理表示不同的值(比如true和2或3,它们在逻辑上都表示“真”,但在物理上两者的表示并不相同)。

与atomic_compare_exchange_weak不同,strong版本的compare-and-exchange操作不允许返回false,即原子对象所封装的值与参数expected的物理内容相同,比较操作一定会为true。不过在某些平台下,若算法本身需要循环操作来做检查,则使用atomic_compare_ex-change_weak会更好。对于某些不需要采用循环操作的算法而言,通常采用atomic_compare_exchange_strong更好。

978-7-111-51399-5-Chapter15-14.jpg

该函数和atomic_compare_exchange_weak()的不同之处在于指定了两个memory_order类型参数。其功能还是比较并替换其包含的值。第二个memory_order类型参数不能是memory_order_release,也不能是memory_order_acq_rel,并且其值要小于第一个memory_order类型参数的值。

978-7-111-51399-5-Chapter15-15.jpg

该函数和atomic_compare_exchange_weak_explicit()类似。其功能与atomic_compare_ex-change_strong相同。二者的不同之处在于增加了两个memory_order类型的参数。其两个新增加参数的意义和使用方法与atomic_compare_exchange_weak_explicit()函数相同。