详解Go sync 同步原语
Go 语言中的 sync
包提供了基本的同步原语,如互斥锁 (sync.Mutex
)、读写锁 (sync.RWMutex
)、WaitGroup、Once 和 Cond 等。这些同步原语可以帮助你在多线程或并发环境中同步访问共享资源,避免竞争条件(race conditions)等问题。
这里给你一个简单的例子来说明如何使用 sync
包中一些常见的同步原语:
使用 sync.Mutex
来保护共享资源:
package main
import (
"fmt"
"sync"
)
// Counter 是一个包含竞态资源的结构体
type Counter struct {
value int
mu sync.Mutex
}
// Increment 方法增加计数
func (c *Counter) Increment() {
c.mu.Lock() // 在修改前加锁
defer c.mu.Unlock() // 方法结束时解锁
c.value++
}
// Value 方法返回当前计数
func (c *Counter) Value() int {
c.mu.Lock() // 在读取前加锁
defer c.mu.Unlock() // 方法结束时解锁
return c.value
}
func main() {
var wg sync.WaitGroup
counter := Counter{}
// 启动 100 个 goroutine 来增加计数
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
counter.Increment()
}()
}
// 等待所有 goroutine 完成
wg.Wait()
// 打印最终计数的值
fmt.Println(counter.Value())
}
这个程序创建了一个 Counter
结构体,它包含一个受到 sync.Mutex
保护的整数值。Increment
方法在增加计数前进行加锁,完成后释放锁,以防止多个 goroutine 同时修改它。Value
方法在返回计数前也进行加锁和释放锁,保证了读取时的数据安全。
使用 sync.WaitGroup
来等待一组 goroutine 完成:
在上面的例子中,我们使用了 sync.WaitGroup
来等待所有启动的 goroutine 完成增加计数的工作。每启动一个 goroutine,我们就调用 wg.Add(1)
来增加等待计数,而每个 goroutine 完成时,会调用 wg.Done()
来减少等待计数。wg.Wait()
会阻塞,直到所有等待计数归零,表示所有 goroutine 都完成了工作。
实际开发中,Go 的 sync
包非常强大,可以用于解决多种并发和同步问题。在编写并发程序时,理解并正确使用这些同步原语极其重要,能够帮助你避免出现竞态条件、死锁以及其他并发相关的问题。这些示例和说明应该给你一个如何开始使用 sync
包的良好起点。随着实践的深入,你会发现更多高级用法以解决更复杂的并发问题。
(notepad++ 替代) Notepad++的替代品都有什么 推荐4款更牛的代码编辑器 Notepad++替代品:四款优秀编辑器 全网首发(图文详解1)
(植物大战僵尸自动收集阳光修改器) 植物大战僵尸修改器大全 植物大战僵尸修改器使用指南 全网首发(图文详解1)