商城首页欢迎来到中国正版软件门户

您的位置:首页 >Golang sync包实现goroutine同步方法

Golang sync包实现goroutine同步方法

  发布于2026-02-08 阅读(0)

扫一扫,手机访问

sync.Mutex 适合保护共享变量,需在访问前 Lock、结束后 Unlock;避免返回带锁字段指针;sync.Once 保证初始化仅一次且不可重置;sync.WaitGroup 要先 Add 再 go,用 defer Done;sync.RWMutex 适用于读多写少场景。

如何使用Golang的sync包同步goroutine_Golang并发同步与互斥操作方法

sync.Mutex 适合保护共享变量,但别在返回值里传指针

多个 goroutine 同时读写一个 intmap 或结构体字段时,不加锁大概率触发 fatal error: concurrent map writes 或读到脏数据。用 sync.Mutex 最直接:在访问前调用 mu.Lock(),结束后立刻 mu.Unlock()

常见错误是把带锁的结构体字段以指针形式返回,比如:

func (c *Counter) GetPtr() *int {
    c.mu.Lock()
    return &c.val // 危险!外部可绕过锁直接改
}

应该改为只返回值,或提供受控的修改方法:

  • 返回副本:return c.val
  • 封装操作:func (c *Counter) Inc() { c.mu.Lock(); defer c.mu.Unlock(); c.val++ }
  • 避免暴露内部状态,尤其别让调用方决定何时解锁

sync.Once 保证初始化只执行一次,但不能重置

sync.OnceDo() 方法适合做单例初始化、配置加载、资源首次创建等场景。它内部用原子操作 + 互斥锁实现,线程安全且开销极小。

注意它不可重置、不可重复使用。一旦 once.Do(f) 执行过,再调用同个 once 实例的 Do() 将直接返回,不管 f 是否 panic(panic 会导致该次调用失败,但标记仍设为已执行)。

  • 不要试图通过新建 sync.Once 变量来“重试”初始化
  • 如果初始化逻辑可能失败且需重试,应自己封装重试逻辑,而不是依赖 sync.Once
  • 典型误用:if err := initDB(); err != nil { once.Do(initDB) } —— 这不会重试,因为 once 已标记完成

sync.WaitGroup 用于等待 goroutine 结束,别漏掉 Add 或 Done

sync.WaitGroup 是等待一组 goroutine 完成的最常用方式。核心是三步:wg.Add(n)、启动 goroutine、每个 goroutine 结尾调用 wg.Done(),主 goroutine 调用 wg.Wait() 阻塞等待。

最容易出错的是调用时机:Add() 必须在 go 语句之前,否则可能 Wait() 已返回而 goroutine 还没被计数;Done() 必须确保执行,哪怕函数 panic,建议用 defer wg.Done()

  • 错误写法:go func() { wg.Add(1); ...; wg.Done() }() —— Add 在 goroutine 内,竞态风险高
  • 正确写法:wg.Add(1); go func() { defer wg.Done(); ... }()
  • 如果 goroutine 数量动态,先算好数量再 Add,别靠 len(ch) 之类估算

sync.RWMutex 读多写少时提升性能,但写锁会阻塞所有读

当共享数据读操作远多于写操作(比如配置缓存、路由表),sync.RWMutex 比普通 Mutex 更高效:多个 goroutine 可同时持有读锁,但写锁会独占,且会阻塞新读锁请求(已有读锁不强制释放)。

关键点在于锁粒度和使用习惯:读锁用 RLock()/RUnlock(),写锁仍用 Lock()/Unlock()。混用时注意——写锁必须等所有当前读锁释放后才能获取。

  • 别在持有读锁时调用可能升级为写锁的函数(Go 不支持锁升级)
  • 写操作频繁时,RWMutex 可能比 Mutex 更慢,因读锁维护有额外开销
  • go tool trace 观察 sync 相关阻塞事件,确认是否真因读锁堆积导致延迟
实际并发控制中,最难的不是选哪个类型,而是判断“哪里需要同步”和“锁的边界是否覆盖全部临界区”。很多 bug 出现在看似无害的辅助函数里——比如一个日志函数悄悄修改了全局计数器,却没加锁。
本文转载于:互联网 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

热门关注