面试题答案
一键面试适合使用条件变量的场景
在Go语言中,当多个goroutine需要协调工作,并且一个或多个goroutine需要等待某个条件满足才能继续执行时,适合使用条件变量。例如,在生产者 - 消费者模型中,消费者goroutine需要等待生产者goroutine生产出数据后才能继续消费。
代码示例
package main
import (
"fmt"
"sync"
"time"
)
var (
cond *sync.Cond
queue []int
mutex sync.Mutex
)
func producer(id int, wg *sync.WaitGroup) {
defer wg.Done()
for i := 0; i < 3; i++ {
mutex.Lock()
item := id*10 + i
queue = append(queue, item)
fmt.Printf("Producer %d produced: %d\n", id, item)
cond.Broadcast()
mutex.Unlock()
time.Sleep(time.Second)
}
}
func consumer(id int, wg *sync.WaitGroup) {
defer wg.Done()
for {
mutex.Lock()
for len(queue) == 0 {
cond.Wait()
}
item := queue[0]
queue = queue[1:]
fmt.Printf("Consumer %d consumed: %d\n", id, item)
mutex.Unlock()
time.Sleep(time.Second)
}
}
你可以使用以下方式调用这些函数:
func main() {
cond = sync.NewCond(&mutex)
var wg sync.WaitGroup
wg.Add(2)
go producer(1, &wg)
go producer(2, &wg)
wg.Add(2)
go consumer(1, &wg)
go consumer(2, &wg)
wg.Wait()
time.Sleep(5 * time.Second)
}
在这个示例中,生产者goroutine向队列中添加数据,并通过cond.Broadcast()
通知等待的消费者。消费者goroutine在队列空时调用cond.Wait()
等待通知,当收到通知且队列中有数据时进行消费。