【Go】数据竞态

1.数据竞态

Blocking(阻塞):是指多个(大于或等于2 个)goroutine在执行过程中,因争夺资源而造成的一种相互等待的现象。

Race(竞态):数据竞态是指多个(大于或等于2 个)goroutine在执行过程中,读写相同数据的情况,必须存在至少一方写。另外,如果所有 goroutine 都只是进行读操作,那将不会构成数据争用
不同读写协程的执行时机不同导致结果出乎意料的结果

2.监测数据竞态

go run -race main.go
go build -race main.go
go test -race a_test.go
go install -race main.go

3.修复 Data Races的4种方式

A、等待组(sync.WaitGroup)

使用WaitGroup来Blocking(阻塞),控制读写协程的执行顺序

B、通道channel,也就是消息机制

使用Channel来Blocking(阻塞),控制读写协程的执行顺序

C、原子函数 (sync/atomic)

一个或者多个操作在 CPU 执行的过程中不被中断的特性,称为原子性(atomicity) 。这些操作对外表现成一个不可分割的整体,他们要么都执行,要么都不执行,外界不会看到他们只执行到一半的状态。

D、互斥锁(sync.Mutex)

sync.Mutex是Go标准库中常用的一个排外锁。当一个 goroutine 获得了这个锁的拥有权后, 其它请求锁的 goroutine 就会阻塞在 Lock 方法的调用上,直到锁被释放。

互斥锁是用来保护一段逻辑,原子操作用于对一个变量的更新保护。
底层实现: Mutex由操作系统的调度器实现,而atomic包中的原子操作则由底层硬件指令直接提供支持,这些指令在执行的过程中是不允许中断的,因此原子操作可以在lock-free的情况下保证并发安全,并且它的性能也能做到随CPU个数的增多而线性扩展。

4.for循环相关的数据竞态

for循环中go协程作用域,导致和期望数据不一致

  1. goroutine加参数
  2. 将for循环中的变量作用域缩小到goroutine中

for goroutine 中的执行顺序是 无序的 ,业务中做的时候需要了解

参考:
https://mp.weixin.qq.com/s/hWENZOB70Y6Vz2TKdJEUmg
https://cloud.tencent.com/developer/article/1882225

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值