文章目录
并发安全性与原子操作

- 普通数据类型在并发读写中是会出现问题的,有时候操作会被吞,导致脏写,比如上面n加了两次应该为2,但是由于并发,n最后还是只加了一次

读写锁
- sync.RWMutex
- 读锁和写锁之间是互斥的,写锁之间互斥,读锁之间不互斥

- 写-写 不可以

- 写-读 不可以

- 读-读 可以

- 读-写 不可以

- 释放锁后,就可以上锁成功了

- 用锁来保证原子性操作
分布式锁
- 一般我们在实际中会把go程序部署在多台服务器中同时运行一模一样的代码
- 但是如果多人同时运行一样的代码,可能会出现问题
- 分布式锁就是一个全局变量,独立于服务器,谁抢到这个锁谁就可以执行
- 简单的分布式锁可以借助redis实现,setnx
go
// 尝试获取锁
result, err := rc.SetNX(context.Background(), "lock:resource1", "clientA", 10*time.Second).Result()
if err != nil {
// 处理错误(如连接问题)
log.Fatal(err)
}
if result {
// 获取锁成功,执行业务逻辑
defer rc.Del(context.Background(), "lock:resource1") // 完成后释放锁
// ...
} else {
// 锁已被其他客户端持有
fmt.Println("获取锁失败")
}
- rc.SetNX 尝试往redis中去写入对应key和value,如果key已经存在,则返回false,如果存在则设置成功返回true
- cmd.Err() != nil 证明发生异常了,比如服务器突然断开了


- 只有一个上锁成功,只会输出一次上锁成功

- 协程0 上锁成功