面试题答案
一键面试在Go语言中,当闭包对共享变量进行读写操作时,可以采用以下几种方法保证数据一致性和安全性:
使用互斥锁(sync.Mutex
)
互斥锁可以确保在同一时间只有一个goroutine能够访问共享变量。
package main
import (
"fmt"
"sync"
)
var (
mu sync.Mutex
count int
)
func main() {
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
mu.Lock()
count++
fmt.Println("Incremented count:", count)
mu.Unlock()
}()
}
wg.Wait()
}
使用读写锁(sync.RWMutex
)
如果读操作远多于写操作,可以使用读写锁,允许多个goroutine同时进行读操作,但写操作时会独占锁。
package main
import (
"fmt"
"sync"
)
var (
rwmu sync.RWMutex
value int
)
func read(id int) {
rwmu.RLock()
fmt.Printf("Reader %d read value: %d\n", id, value)
rwmu.RUnlock()
}
func write(id int) {
rwmu.Lock()
value++
fmt.Printf("Writer %d incremented value: %d\n", id, value)
rwmu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
write(id)
}(i)
}
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
read(id)
}(i)
}
wg.Wait()
}
使用通道(chan
)
通过通道来传递对共享变量的操作请求,由一个goroutine专门负责处理这些请求,从而保证数据一致性。
package main
import (
"fmt"
"sync"
)
type Op struct {
typ string
done chan struct{}
}
func worker() {
var count int
ch := make(chan Op)
go func() {
for op := range ch {
switch op.typ {
case "increment":
count++
fmt.Println("Incremented count:", count)
}
close(op.done)
}
}()
// 模拟其他goroutine发送操作请求
var wg sync.WaitGroup
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
done := make(chan struct{})
ch <- Op{"increment", done}
<-done
}()
}
wg.Wait()
close(ch)
}
func main() {
worker()
}