从不同线程读取值安全吗?
在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中文网其他相关文章!