使用sync.Mutex可确保多goroutine下对共享变量的安全访问,通过加锁解锁机制防止数据竞争;2. sync.RWMutex在读多写少场景中提升性能,允许多个读操作并发执行,写操作则独占资源;3. sync.Once保证初始化逻辑仅执行一次,适用于单例或全局初始化;4. sync.WaitGroup用于主线程等待所有子goroutine完成任务,实现“分发-等待”同步模式。

在Go语言中,sync包提供了多种工具来实现并发安全,尤其是在多个goroutine访问共享资源时避免数据竞争。正确使用这些同步原语,能有效保证程序的稳定性和正确性。
当多个goroutine需要读写同一个变量时,使用 sync.Mutex 可以确保同一时间只有一个goroutine能访问该资源。
示例:安全地增加计数器
var (
counter int
mu sync.Mutex
)
func increment() {
mu.Lock()
defer mu.Unlock()
counter++
}
每次调用 increment 时都会先加锁,操作完成后解锁。其他goroutine必须等待锁释放才能进入临界区。
立即学习“go语言免费学习笔记(深入)”;
如果场景中读操作远多于写操作,使用 sync.RWMutex 更高效。它允许多个读操作同时进行,但写操作独占。
示例:并发读取配置信息
var (
config map[string]string
rwMu sync.RWMutex
)
func readConfig(key string) string {
rwMu.RLock()
defer rwMu.RUnlock()
return config[key]
}
func updateConfig(key, value string) {
rwMu.Lock()
defer rwMu.Unlock()
config[key] = value
}
读操作使用 RLock,写操作使用 Lock,这样在频繁读、偶尔写的场景下性能更好。
sync.Once 用于保证某个函数在整个程序运行期间只执行一次,常用于单例模式或全局初始化。
var once sync.Once
var instance *MyStruct
func getInstance() *MyStruct {
once.Do(func() {
instance = &MyStruct{}
})
return instance
}
即使多个goroutine同时调用 getInstance,Do 中的初始化代码也只会运行一次。
sync.WaitGroup 用于主线程等待所有子goroutine完成任务,适合“分发-等待”场景。
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d done\n", id)
}(i)
}
wg.Wait() // 阻塞直到所有 Done 被调用
注意:Add 应在 goroutine 启动前调用,否则可能产生竞态。
基本上就这些。合理选择 sync 提供的工具,可以简洁高效地实现并发安全。关键是理解每种原语的适用场景,避免过度加锁影响性能。
以上就是Golang如何使用sync实现并发安全的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号