Go语言中sync.Mutex的作用

1、使用互斥锁的目的

connLock 用于保护全局的 UDP 连接 conn。无论哪个函数需要访问 conn,都必须通过 connLock 进行同步

2、介绍

  • 互斥锁用于确保在同一时间只有一个goroutine可以访问共享资源,防止数据竞争。
  • sync.Mutex 的设计目的是通过锁机制确保同一时刻只有一个协程访问共享资源。

如果被多个函数访问,那么需要将conn设置为全局变量

3、为什么要设置成全局变量

如果不同的函数使用不同的锁来保护同一个资源,反而会导致同步问题,因为锁之间无法协调,可能导致多个goroutine同时访问资源

var conn *net.UDPConn
var connLock sync.Mutex

在RequestRegister函数中使用了connLock.Lock()和defer connLock.Unlock()

当RequestNotify函数也需要访问或修改conn时,同样需要加锁,因为任何对共享资源的并发访问都需要通过锁来同步。

4、如何使用

因为connLock是用于保护conn的,无论哪个函数访问conn,都必须先获取这个锁。因此,在RequestNotify中使用connLock.Lock()和Unlock()是必要的,以确保在修改或读取conn时不会有其他goroutine同时进行,避免竞态条件。

在使用互斥锁时,必须确保在函数的所有退出路径中都释放锁,包括在发生错误时。使用defer语句可以很好地处理这一点,因为它会在函数返回前执行Unlock,无论函数是正常返回还是因为错误提前返回。

connLock.Lock()
defer connLock.Unlock()

在RequestRegister函数中使用Lock和UnLock之后,在RequestNotify函数中可以使用相同的connLock进行加锁和解锁,可以有效保护共享资源conn,避免并发访问导致的问题

5、关键原理说明

  1. 锁的作用域

    • connLock 保护的是 conn 这个共享资源,而不是特定函数

    • 任何需要访问 conn 的代码路径(无论是注册、通知还是其他操作)必须通过同一把锁

  2. 协程安全

    • 多个协程可能同时触发 RequestRegister 和 RequestNotify

    • 锁机制确保同一时间只有一个协程操作连接,避免并发写入导致的崩溃或数据混乱

  3. 死锁预防:

    • 使用 defer connLock.Unlock() 确保即使发生 panic 或提前 return 也能释放锁

    • 避免在锁内调用其他可能获取同一锁的函数(防止递归锁)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值