面试题答案
一键面试生产者 - 消费者模型逻辑
- 生产者逻辑:生产者负责生成数据,并将数据放入共享的缓冲区中。当缓冲区已满时,生产者需要等待,直到有空间可用。
- 消费者逻辑:消费者从共享缓冲区中取出数据进行处理。当缓冲区为空时,消费者需要等待,直到有数据可用。
- 条件变量的作用:条件变量用于协调生产者和消费者之间的同步。它允许生产者在缓冲区满时等待,直到消费者从缓冲区中取出数据,腾出空间后通知生产者;同理,消费者在缓冲区空时等待,直到生产者向缓冲区中放入数据后通知消费者。
代码示例
package main
import (
"fmt"
"sync"
)
const bufferSize = 5
var (
buffer = make([]int, 0, bufferSize)
mutex sync.Mutex
cond = sync.NewCond(&mutex)
wg sync.WaitGroup
)
// 生产者函数
func producer(id int) {
defer wg.Done()
for i := 0; i < 10; i++ {
mutex.Lock()
for len(buffer) == bufferSize {
cond.Wait()
}
buffer = append(buffer, i)
fmt.Printf("Producer %d produced %d\n", id, i)
cond.Broadcast()
mutex.Unlock()
}
}
// 消费者函数
func consumer(id int) {
defer wg.Done()
for {
mutex.Lock()
for len(buffer) == 0 {
cond.Wait()
}
data := buffer[0]
buffer = buffer[1:]
fmt.Printf("Consumer %d consumed %d\n", id, data)
cond.Broadcast()
mutex.Unlock()
if data == 9 {
break
}
}
}
func main() {
wg.Add(2 + 2)
go producer(1)
go producer(2)
go consumer(1)
go consumer(2)
wg.Wait()
}
在上述代码中:
buffer
是共享的缓冲区。mutex
用于保护对缓冲区的访问。cond
是条件变量,用于通知生产者和消费者状态的改变。producer
函数生成数据并放入缓冲区,当缓冲区满时等待,放入数据后通知消费者。consumer
函数从缓冲区取出数据,当缓冲区空时等待,取出数据后通知生产者。main
函数启动两个生产者和两个消费者,并等待它们完成。