优化策略
- 互斥锁(Mutex):使用
sync.Mutex
来保护共享资源,在对共享资源进行读写操作前获取锁,操作完成后释放锁,确保同一时间只有一个协程能访问共享资源。
- 读写锁(RWMutex):如果读操作远多于写操作,可以使用
sync.RWMutex
。读操作时可以多个协程同时进行,写操作时需要独占锁,防止其他读写操作。
- 通道(Channel):通过通道在协程间传递数据,避免直接对共享资源进行操作,利用通道的阻塞和同步机制来控制数据流动。
- 原子操作:对于简单的共享变量(如计数器),可以使用
sync/atomic
包中的原子操作函数,它们在硬件层面保证操作的原子性,避免锁的开销。
关键代码示例
- 使用互斥锁
package main
import (
"fmt"
"sync"
)
var (
mu sync.Mutex
count int
)
func increment(wg *sync.WaitGroup) {
defer wg.Done()
mu.Lock()
count++
mu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final count:", count)
}
- 使用读写锁
package main
import (
"fmt"
"sync"
)
var (
rwmu sync.RWMutex
value int
)
func read(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.RLock()
fmt.Println("Read value:", value)
rwmu.RUnlock()
}
func write(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.Lock()
value++
fmt.Println("Write value:", value)
rwmu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
if i%2 == 0 {
wg.Add(1)
go write(&wg)
} else {
wg.Add(1)
go read(&wg)
}
}
wg.Wait()
}
- 使用通道
package main
import (
"fmt"
"sync"
)
func producer(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
}
func consumer(ch chan int, wg *sync.WaitGroup) {
defer wg.Done()
for val := range ch {
fmt.Println("Consumed:", val)
}
}
func main() {
var wg sync.WaitGroup
ch := make(chan int)
wg.Add(2)
go producer(ch, &wg)
go consumer(ch, &wg)
wg.Wait()
}
- 使用原子操作
package main
import (
"fmt"
"sync"
"sync/atomic"
)
var count int64
func increment(wg *sync.WaitGroup) {
defer wg.Done()
atomic.AddInt64(&count, 1)
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go increment(&wg)
}
wg.Wait()
fmt.Println("Final count:", atomic.LoadInt64(&count))
}