点赞&关注的竞态问题|青训营笔记

180 阅读2分钟

点赞&关注的竞态问题|青训营笔记

这是我参与「第三届青训营 -后端场」笔记创作活动的的第1篇笔记。

问题发现

在抖音大项目的点赞操作和关注操作中,会存在同时多用户进行操作时,可能会出现输出结果不确定的情况,也就是竞态。

什么是竞态

image.png

竞态条件是指在并发环境下,当同一时刻有多个函数访问同一个临界资源时,由于多个事件的并发执行顺序的不确定,从而导致程序输出结果的不确定,这种情况我们称之为竞态条件 (Race Conditions)或者竞争冒险(race hazard)。

所以在大量用户点赞时,添加点赞数量会触发竞态条件,导致数据结果不确定导致错误。

检查竞态的方法

检查竟态

Go(从v1.1开始)具有内置的数据竞争检测器,可以使用它来查明潜在的数据竞争条件。

使用它就像-race在普通的Go命令行工具中添加标志一样简单。

运行时检查竟态的命令:go run -race main.go 构建时检查竟态的命令:go build -race main.go 测试时检查竟态的命令:go test -race main.go

所有避免产生竟态背后的核心原则是防止对同一变量或内存位置同时进行读写访问。
转载于作者:goonwalk 链接:juejin.cn/post/702636…

解决方案

使用互斥锁Mutex

 var mu sync.Mutex
 // 调用结构体对象的Lock方法将会锁定该对象中的变量;如果没有,将会阻塞其他调用,直到该互斥对象的Unlock方法被调用
 mu.Lock()
 // 直到该方法返回,该实例对象才会被解锁
 defer mu.Unlock()
 dbRes := DB.Model(&model.Follow{}).Create(&subscribe)

在调用代码前lock住,调用后释放来解决此问题。 当有多个写入与读取操作混合在一起,使用Mutex互斥可以保证读写的值与预期结果一致。