1. 使用互斥锁(mutex)
互斥锁(mutex)是一种常用的同步原语,用于防止多个协程同时访问共享资源。
package main import ( "fmt" "sync" ) var ( counter int mutex sync.mutex ) func increment(wg *sync.waitgroup) { defer wg.done() mutex.lock() counter mutex.unlock() } func main() { var wg sync.waitgroup for i := 0; i < 1000; i { wg.add(1) go increment(&wg) } wg.wait() fmt.println("final counter:", counter) }
2. 使用channel
go
语言的核心理念之一就是“不通过共享内存来通信,而是通过通信来共享内存”。我们可以通过创建一个channel
,然后通过发送和接收消息的方式来读写共享变量。这种方式在处理并发问题时非常有用,因为channel
本身就提供了安全性。
package main import ( "fmt" ) func increment(counter chan int, done chan bool) { for i := 0; i < 1000; i { value := <-counter value counter <- value } done <- true } func main() { counter := make(chan int, 1) counter <- 0 done := make(chan bool) for i := 0; i < 10; i { go increment(counter, done) } for i := 0; i < 10; i { <-done } fmt.println("final counter:", <-counter) }
3. 读写锁(sync.rwmutex)
如果程序中的读操作远多于写操作,那么使用读写锁可能会比互斥锁更有效率。读写锁允许多个协程同时读取变量,但是只允许同一时刻只有一个协程进行写入操作。
package main import ( "fmt" "sync" ) var ( counter int rwmutex sync.rwmutex ) func read(wg *sync.waitgroup) { defer wg.done() rwmutex.rlock() fmt.println("counter:", counter) rwmutex.runlock() } func write(wg *sync.waitgroup) { defer wg.done() rwmutex.lock() counter rwmutex.unlock() } func main() { var wg sync.waitgroup for i := 0; i < 10; i { wg.add(1) go read(&wg) } for i := 0; i < 10; i { wg.add(1) go write(&wg) } wg.wait() }
4. 原子操作(sync/atomic包)
对于一些简单的数值或者布尔类型,我们可以使用原子操作来读写共享变量。
package main import ( "fmt" "sync" "sync/atomic" ) var counter int64 func increment(wg *sync.waitgroup) { defer wg.done() atomic.addint64(&counter, 1) } func main() { var wg sync.waitgroup for i := 0; i < 1000; i { wg.add(1) go increment(&wg) } wg.wait() fmt.println("final counter:", counter) }
5. sync.once
如果共享变量只需要被初始化一次,可以使用sync.once
来确保初始化的并发安全性。
package main import ( "fmt" "sync" ) var ( once sync.once initvalue int ) func initialize() { fmt.println("initializing...") initvalue = 42 } func dosomething() { once.do(initialize) fmt.println("value:", initvalue) } func main() { var wg sync.waitgroup for i := 0; i < 10; i { wg.add(1) go func() { defer wg.done() dosomething() }() } wg.wait() }
最后给大家推荐一个linuxc/c 高级架构系统教程的学习资源与课程,可以帮助你有方向、更细致地学习c/c 后端开发,具体内容请见 https://xxetb.xetslk.com/s/1o04ub