MST

星途 面试题库

面试题:Go中条件变量在生产者 - 消费者模型里的应用

在Go语言中,描述如何使用条件变量来实现一个简单的生产者 - 消费者模型。请说明生产者和消费者的逻辑,以及条件变量在其中起到的作用,并给出相应的代码示例。
17.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

生产者 - 消费者模型逻辑

  1. 生产者逻辑:生产者负责生成数据,并将数据放入共享的缓冲区中。当缓冲区已满时,生产者需要等待,直到有空间可用。
  2. 消费者逻辑:消费者从共享缓冲区中取出数据进行处理。当缓冲区为空时,消费者需要等待,直到有数据可用。
  3. 条件变量的作用:条件变量用于协调生产者和消费者之间的同步。它允许生产者在缓冲区满时等待,直到消费者从缓冲区中取出数据,腾出空间后通知生产者;同理,消费者在缓冲区空时等待,直到生产者向缓冲区中放入数据后通知消费者。

代码示例

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()
}

在上述代码中:

  1. buffer 是共享的缓冲区。
  2. mutex 用于保护对缓冲区的访问。
  3. cond 是条件变量,用于通知生产者和消费者状态的改变。
  4. producer 函数生成数据并放入缓冲区,当缓冲区满时等待,放入数据后通知消费者。
  5. consumer 函数从缓冲区取出数据,当缓冲区空时等待,取出数据后通知生产者。
  6. main 函数启动两个生产者和两个消费者,并等待它们完成。