MST

星途 面试题库

面试题:Go sync.Cond的复杂使用场景

假设你正在开发一个生产者 - 消费者模型,其中生产者和消费者的数量不固定,且消费者需要根据不同条件消费数据。请描述如何使用Go的sync.Cond来实现这种复杂的同步机制,并写出核心代码片段。
26.6万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 原理
    • sync.Cond 依赖于一个 sync.Locker(通常是 sync.Mutex)。生产者和消费者通过这个条件变量来同步。生产者在生产数据后,通知等待在条件变量上的消费者。消费者根据不同条件决定是否消费数据,如果条件不满足则等待在条件变量上。
  2. 核心代码片段
package main

import (
    "fmt"
    "sync"
)

type Data struct {
    // 数据结构定义
}

var (
    dataQueue []Data
    mu        sync.Mutex
    cond      = sync.NewCond(&mu)
)

// 生产者函数
func producer(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    for i := 0; i < 10; i++ {
        mu.Lock()
        newData := Data{}
        dataQueue = append(dataQueue, newData)
        fmt.Printf("Producer %d produced data\n", id)
        cond.Broadcast()
        mu.Unlock()
    }
}

// 消费者函数
func consumer(id int, wg *sync.WaitGroup) {
    defer wg.Done()
    for {
        mu.Lock()
        for len(dataQueue) == 0 {
            cond.Wait()
        }
        // 这里可以添加不同的消费条件判断
        data := dataQueue[0]
        dataQueue = dataQueue[1:]
        fmt.Printf("Consumer %d consumed data\n", id)
        mu.Unlock()
    }
}

func main() {
    var wg sync.WaitGroup
    numProducers := 3
    numConsumers := 5

    for i := 0; i < numProducers; i++ {
        wg.Add(1)
        go producer(i, &wg)
    }

    for i := 0; i < numConsumers; i++ {
        wg.Add(1)
        go consumer(i, &wg)
    }

    wg.Wait()
}

在上述代码中:

  • producer 函数生产数据并通过 cond.Broadcast() 通知所有等待的消费者。
  • consumer 函数在 dataQueue 为空时通过 cond.Wait() 等待,当被通知且 dataQueue 有数据时消费数据。可以在消费数据前添加不同的条件判断逻辑。