原子操作
1
1 增和减 add将一个int64的变量原子的增加5,减操作用补码来实现,atomic.AddInt64(&counter, 5)
2 比较并交换(compare and swap 简称 CAS)
CompareAndSwapInt32函数接受三个参数。第一个参数的值应该是指向被操作值的指针值。该值的类型即为*int32。后两个参数的类型都是int32类型。它们的值应该分别代表被操作值的旧值和新值。CompareAndSwapInt32函数在被调用之后会先判断参数addr指向的被操作值与参数old的值是否相等。仅当此判断得到肯定的结果之后,该函数才会用参数new代表的新值替换掉原先的旧值。否则,后面的替换操作就会被忽略。这个函数返回一个布尔值,如果替换成功,返回true,否则返回false,
if atomic.CompareAndSwapInt32(&value, v, (v + delta))
3 加载(读) load
原子的读取变量value的值并把它赋给变量v。有了“原子的”这个形容词就意味着,在这里读取value的值的同时,当前计算机中的任何CPU都不会进行其它的针对此值的读或写操作。这样的约束是受到底层硬件的支持的。这样在读取的时候,其它协程无法对其执行写操作,v := atomic.LoadInt32(&value)
4 存储(写) store
在原子的存储某个值的过程中,任何CPU都不会进行针对同一个值的读或写操作。如果我们把所有针对此值的写操作都改为原子操作,那么就不会出现针对此值的读操作因被并发的进行而读到修改了一半的值的情况了。第一个值是原先的值,第二个是要新的值,将第二个赋值给第一个,这个和CAS的写入不同,不会进行值的比较,直接修改,atomic.StoreInt64(&counter, int64(i))
5 交换 swap
与存储与CAS操作类似,但它介于两者之间,会直接用新值修改旧值,但会返回旧值,atomic.SwapInt64(&counter, int64(i))
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
//1 增和减 add //将一个int64的变量原子的增加5,减操作用补码来实现, //atomic.AddInt64(&counter, 5) // //2 比较并交换(compare and swap 简称 CAS) //CompareAndSwapInt32函数接受三个参数。第一个参数的值应该是指向被操作值的指针值。 //该值的类型即为*int32。后两个参数的类型都是int32类型。它们的值应该分别代表被操作值的旧值和新值。 //CompareAndSwapInt32函数在被调用之后会先判断参数addr指向的被操作值与参数old的值是否相等。 //仅当此判断得到肯定的结果之后,该函数才会用参数new代表的新值替换掉原先的旧值。否则,后面的替换操作就会被忽略。 //这个函数返回一个布尔值,如果替换成功,返回true,否则返回false, //if atomic.CompareAndSwapInt32(&value, v, (v + delta)) // //3 加载 load //原子的读取变量value的值并把它赋给变量v。有了“原子的”这个形容词就意味着,在这里读取value的值的同时, //当前计算机中的任何CPU都不会进行其它的针对此值的读或写操作。这样的约束是受到底层硬件的支持的。 //这样在读取的时候,其它协程无法对其执行写操作, //v := atomic.LoadInt32(&value) // //4 存储 store //在原子的存储某个值的过程中,任何CPU都不会进行针对同一个值的读或写操作。如果我们把所有针对此值的写操作都改为原子操作, //那么就不会出现针对此值的读操作因被并发的进行而读到修改了一半的值的情况了。 //第一个值是原先的值,第二个是要新的值,将第二个赋值给第一个, //这个和CAS的写入不同,不会进行值的比较,直接修改, //atomic.StoreInt64(&counter, int64(i)) // //5 交换 swap //与存储与CAS操作类似,但它介于两者之间,会直接用新值修改旧值,但会返回旧值, //atomic.SwapInt64(&counter, int64(i))
https://segmentfault.com/a/1190000037449024
https://www.cnblogs.com/sunsky303/p/7453344.html