前导
所以,互斥锁虽然可以保证临界区代码的串行执行,但却不能保证这些代码执行的原子性atomic operation操作系统只针对二进制位或整数的原子操作提供了支持
sync/atomic提供的原子操作
int32、int64、uint32、uint64、uintptr类型unsafe包中的Pointer

为什么参数类型中,要操作的都是指针?

而unsafe.Pointer类型虽然是指针类型,但是要操作的实际上是指针值,而不是它指向的那个值,所以需要的仍然是指向这个指针值的指针

原子加法操作可以做原子减法吗?

func AddInt32(addr *int32, delta int32) (new int32)func AddUint32(addr *uint32, delta uint32) (new uint32)^uint32(N-1)atomic.AddUint32(&a, ^uint32(10-1))

比较并交换和交换操作有什么不同?

func SwapInt32(addr *int32, new int32) (old int32)func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool)
for {
	// 直到num2的值等于10,就结束自选
	if atomic.CompareAndSwapInt32(&num2, 10, 0) {
		fmt.Println("The second number has gone to zero.")
		break
	}
	time.Sleep(time.Millisecond * 500)
}

如果写操作用的是原子操作,那么读操作还有必要用原子操作吗?

一旦决定要对共享资源保护,就要做到完全保护,不完全的保护和不保护没有什么区别
sync/atomic.Value
  • atomic.Value是开箱即用的,只需要声明一个该类型的变量。它只有两个指针方法,Store和Load。
  • 不能用原子值存储nil,否则会panic。
  • 向原子值存储的第一个值,决定了以后它能存储的类型。比如第一次存储了string类型,后面再存别的类型会panic。
  • 尽量不要向原子值中存储引用类型的值。