golang-标准库(sync/atomic)

这个库是用来保证并发编程数据安全的。提供了对数据进行原子性操作的方法。 初学者对数据的原子性操作不是太理解,sync包的锁就可以保证并发数据的安全,为什么atomic包也可以保证并发的数据安全,它跟加锁的区别又是什么。 简单说一下,锁是编程语言层面提供的保证数据并发安全的一种方式,而原子性的操作函数是操作系统层面提供的方式,C语言中也有_Atomic关键字,也是用来保证并发编程安全的。下面通过例子来认识一下
  • 我们启动1000个协程,对a进行+1的操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    func main() {
    // 启动1000个协程,对a进行+1的操作
    var a int64
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
    wg.Add(1) // 并发组加1
    go func() {
    a++
    wg.Done() // 并发组减1
    }()
    }
    wg.Wait()
    println(a) // 打印a
    }

上面的运行结果并不是1000,下面是我的运行结果

  • 下面用加锁的方式来保证数据的安全
    的操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    func main() {
    // 启动1000个协程,对a进行+1的操作
    var a int64
    var wg sync.WaitGroup
    var s sync.Mutex
    for i := 0; i < 1000; i++ {
    wg.Add(1) // 并发组加1
    go func() {
    s.Lock() // 加锁
    defer s.Unlock() // 释放所
    a++
    wg.Done() // 并发组减1
    }()
    }
    wg.Wait()
    println(a) // 打印a
    }

上面结果你再运行,就能保证结果是1000,加锁保证的数据的安全。

  • atomic包提供了原子性同步算法,下面看atomic包怎么保证数据安全
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    func main() {
    // 启动1000个协程,对a进行+1的操作
    var a int64
    var wg sync.WaitGroup
    for i := 0; i < 1000; i++ {
    wg.Add(1) // 并发组加1
    go func() {
    atomic.AddInt64(&a, 1) // 原子性的对a的值进行加1,操作数据的时候,其它线程不能修改a
    wg.Done() // 并发组减1
    }()
    }
    wg.Wait()
    println(a) // 打印a
    }
上面的代码运行结果也是正确的。可以看到,atomic包可以实现与加锁相同的功能,甚至它的效率要高于加锁。但atomic包只提供了一系列的同步算法,也就是只对数据进行加减,修改这些操作。当原子性涉及多段逻辑的时候(比如先查询数据库,再请求某个webservice接口,再更新数据库,要保证这种逻辑的原子性,就不是atomic包能做的了),就只能用锁或者channel了。
  • 下面是atomic包提供的一几个方法,比较简单,都是对数据进行简单的修改操作:
1
2
3
func AddInt64(addr *int64, delta int64) (new int64) => AddInt64原子性的将val的值添加到*addr并返回新值。
func StoreInt32(addr *int32, val int32) => StoreInt32原子性的将val的值保存到*addr
func SwapUint32(addr *uint32, new uint32) (old uint32) => SwapUint32原子性的将新值保存到*addr并返回旧值。
作者

itpika

发布于

2020-06-03 13:31:38

更新于

2021-01-28 16:44:10

许可协议

评论