MST
星途 面试题库

面试题:Go中Channel数据发送与接收的常见场景及代码实现

请描述在Go语言中,使用Channel进行数据发送与接收的两个常见应用场景,并分别给出对应的代码示例。同时,解释一下如何通过Channel来实现简单的生产者 - 消费者模型。
46.3万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

应用场景一:数据传递

在并发编程中,不同的goroutine之间常常需要传递数据,Channel提供了一种安全、高效的方式。

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

    go func() {
        data := 42
        ch <- data
    }()

    received := <-ch
    fmt.Println("Received:", received)
}

在上述代码中,一个匿名的goroutine将数据42发送到ch这个channel中,主goroutine从ch中接收数据并打印。

应用场景二:同步

Channel可用于同步goroutine的执行。例如,当一个goroutine完成某些任务后,通过Channel通知其他goroutine。

package main

import (
    "fmt"
)

func main() {
    done := make(chan struct{})

    go func() {
        // 模拟一些工作
        fmt.Println("Working...")
        close(done)
    }()

    <-done
    fmt.Println("Work is done.")
}

这里,匿名goroutine在完成工作后关闭done这个channel,主goroutine通过接收done中的数据(这里使用struct{}类型,因为不需要传递具体数据,仅用于同步)来得知工作已完成。

生产者 - 消费者模型实现

生产者 - 消费者模型是一种经典的并发设计模式。生产者将数据放入Channel,消费者从Channel中取出数据进行处理。

package main

import (
    "fmt"
)

func producer(ch chan<- int) {
    for i := 0; i < 5; i++ {
        ch <- i
        fmt.Printf("Produced: %d\n", i)
    }
    close(ch)
}

func consumer(ch <-chan int) {
    for data := range ch {
        fmt.Printf("Consumed: %d\n", data)
    }
}

func main() {
    ch := make(chan int)

    go producer(ch)
    go consumer(ch)

    // 防止主程序退出
    select {}
}

在上述代码中,producer函数作为生产者,向ch这个channel发送数据,并在发送完后关闭chconsumer函数作为消费者,通过for... range循环从ch中接收数据,直到ch被关闭。主函数中启动了生产者和消费者的goroutine,并使用select {}来防止主程序过早退出。