首页 >后端开发 >Golang >如何安全地读取 Go 中不同 Goroutine 的值?

如何安全地读取 Go 中不同 Goroutine 的值?

Barbara Streisand
Barbara Streisand原创
2024-12-25 09:53:35453浏览

How to Safely Read Values from Different Goroutines in Go?

从不同线程读取值安全吗?

在Go中,当涉及多个goroutine时,对值的安全并发访问需要同步,尤其是当其中至少有一个执行写入操作。在给定的场景中,有必要实现同步以防止未定义的行为。

推荐方法:利用互斥体

通道虽然是消息传递的一个选项,但可能会引入由于主线程中消息检索所需的同步,带来了不必要的复杂性。相反,建议使用读写互斥体 (sync.RWMutex)。这些锁通过强制获取修改操作(工作线程)和只读访问状态检索(主线程)来保护数据。

示例实现

type Worker struct {
    iterMu sync.RWMutex
    iter   int
}

func (w *Worker) Iter() int {
    w.iterMu.RLock()
    defer w.iterMu.RUnlock()
    return w.iter
}

func (w *Worker) setIter(n int) {
    w.iterMu.Lock()
    w.iter = n
    w.iterMu.Unlock()
}

这种方法确保修改迭代计数的工作线程获取写锁,而读取计数的主线程获取读锁

替代方案:原子操作

sync/atomic 包提供原子操作,可以对特定数据类型(例如整数)进行无同步修改。它通过将读取和修改操作限制为其原子函数来确保完整性。

type Worker struct {
    iter int64
}

func (w *Worker) Iter() int64 {
    return atomic.LoadInt64(&w.iter)
}

func (w *Worker) setIter(n int64) {
    atomic.StoreInt64(&w.iter, n)
}

func (w *Worker) incIter() {
    atomic.AddInt64(&w.iter, 1)
}

这种方法提供了更简单的同步机制,但请注意,它仅适用于特定数据类型。

通过采用使用这些方法之一,您可以安全地从不同线程中的工作线程读取值,保证数据完整性并避免未定义的行为。

以上是如何安全地读取 Go 中不同 Goroutine 的值?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn