如何在 Go 中实现变量的线程安全
在 Java 中,同步变量的概念保证只有单个线程可以执行任何给定时间的特定代码块。然而,Go 没有提供显式的同步关键字。
基本原理
Go 提倡一种不同的线程同步方法,其指导原则是:“不要通过共享进行通信”记忆;相反,通过交流来共享记忆。”这意味着避免直接访问共享内存并选择基于通信的机制,例如通道。
基于互斥锁的同步
如果您遇到需要互斥锁的场景,这是如何实现它的转:
var ( mu sync.Mutex protectMe int ) func getMe() int { mu.Lock() me := protectMe mu.Unlock() return me } func setMe(me int) { mu.Lock() protectMe = me mu.Unlock() }
改进
原子同步
如果需要保护单个值,请考虑使用sync/atomic包:
var protectMe int32 func getMe() int32 { return atomic.LoadInt32(&protectMe) } func setMe(me int32) { atomic.StoreInt32(&protectMe, me) }
基于沟通方法
Go 鼓励使用通道进行 goroutine 间通信,从而消除对共享变量的需求。例如,在发布者-订阅者模式中:
type topic struct { subscribing []chan int } var t = &topic{} func subscribe() chan int { ch := make(chan int) t.subscribing = append(t.subscribing, ch) return ch } func publish(v int) { for _, ch := range t.subscribing { ch <- v } }
此方法可确保线程安全通信而不共享内存。
以上是如何在 Go 中实现线程安全:互斥体、原子或通道?的详细内容。更多信息请关注PHP中文网其他相关文章!