美文网首页Go
Go sync/atomic包Load和Store并发不安全

Go sync/atomic包Load和Store并发不安全

作者: parker7 | 来源:发表于2018-10-19 14:49 被阅读0次

前言:为了保证并发安全,go语言中可以使用原子操作。其执行过程不能被中断,这也就保证了同一时刻一个线程的执行不会被其他线程中断,也保证了多线程下数据操作的一致性。

1.sync/atomic包
2.Load和Store并发不安全

1.sync/atomic包

在atomic包中对几种基础类型提供了原子操作,包括int32,int64,uint32,uint64,uintptr,unsafe.Pointer。
对于每一种类型,提供了五类原子操作分别是

  • Add, 增加和减少
  • CompareAndSwap, 比较并交换
  • Swap, 交换
  • Load , 读取
  • Store, 存储

2.Load和Store并发不安全

Load和Store操作对应与变量的原子性读写,许多变量的读写无法在一个时钟周期内完成,而此时执行可能会被调度到其他线程,无法保证并发安全。
⚠️Load 只保证读取的不是正在写入的值,Store只保证写入是原子操作。
所以在使用的时候要注意。
下面简单示例:

package main

import (
    "sync"
    "sync/atomic"
    "fmt"
)

var (
    wg  sync.WaitGroup
    mu  sync.Mutex
    num int32
)

func wrap(callback func()) {
    wg.Add(1)
    go func() {
        callback()
        wg.Done()
    }()
}

// go build -race
func main() {
    // 1099 、892, 并发不安全
    //wrap(incNumAtomic)
    //wrap(incNumAtomic)

    // 1200, 并发安全
    wrap(incNumAtomic2)
    wrap(incNumAtomic2)

    wg.Wait()
    fmt.Printf("num=%d\n", num)
}

func incNumAtomic() {
    for i := 0; i < 600; i++ {
        // atomic.Load*系列函数只能保证读取的不是正在写入的值(比如只被修改了一半的数据)
        // 同样的atomic.Store* 只保证写入是原子操作(保证写入操作的完整性)
        val := atomic.LoadInt32(&num)
        atomic.StoreInt32(&num, val+1)
    }
}

func incNumAtomic2() {
    for i := 0; i < 600; i++ {
        atomic.AddInt32(&num, 1)
    }
}

总结

点击👇查看源码,哈哈哈...

Github Demo

相关文章

  • Go sync/atomic包Load和Store并发不安全

    前言:为了保证并发安全,go语言中可以使用原子操作。其执行过程不能被中断,这也就保证了同一时刻一个线程的执行不会被...

  • 更简的并发代码,更强的并发控制

    有没感觉 Go 的 sync 包不够用?有没遇到类型没有 sync/atomic 支持?我们一起看看 go-zer...

  • Go sync.Mutex

    Go语言提供了sync包和channel机制来解决并发机制中不同goroutine之间的同步和通信 锁 Locke...

  • sync包介绍

    sync包使用官方文档:http://devdocs.io/go/sync/index#Map Go中sync包包...

  • golang atomic包的使用

    go语言提供的原子操作都是非侵入式的,它们由标准库代码包sync/atomic中的众多函数代表。 我们调用syn...

  • atomic的使用,原子操作

    atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的。 下面内容摘秒自《GO并发编程实战》—...

  • Go 专栏|并发编程:goroutine,channel 和 s

    原文链接: Go 专栏|并发编程:goroutine,channel 和 sync[https://mp.weix...

  • rwmutex.go

    概述 rwmutex.go即读写锁,内部基于atomic和sync.mutex实现,提供四个方法 RLock 读锁...

  • go 中的 sync.Map

    sync.map sync.Map 的使用和内置的 map 类型一样,只不过它是并发安全的。 Store:存储一对...

  • go 中的 原子操作

    Go语言中提供的原子操作都是非侵入式的,在标准库代码包sync/atomic中提供了相关的原子函数。 增或减 原子...

网友评论

    本文标题:Go sync/atomic包Load和Store并发不安全

    本文链接:https://www.haomeiwen.com/subject/zeiyzftx.html