MST

星途 面试题库

面试题:Go语言匿名函数在并发编程中的应用

在Go语言的并发编程场景下,使用匿名函数结合goroutine和channel实现一个简单的生产者 - 消费者模型。生产者匿名函数生成1到100的整数并发送到channel,消费者匿名函数从channel接收数据并打印。阐述在这个过程中匿名函数如何与goroutine及channel协同工作,以及可能遇到的同步问题及解决办法。
34.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

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

    // 生产者匿名函数
    go func() {
        for i := 1; i <= 100; i++ {
            ch <- i
        }
        close(ch)
    }()

    // 消费者匿名函数
    go func() {
        for num := range ch {
            fmt.Println(num)
        }
    }()

    // 防止主函数退出
    select {}
}

协同工作原理

  1. 匿名函数与goroutine:通过go关键字将匿名函数包装成goroutine并发执行。生产者匿名函数负责生成数据,消费者匿名函数负责处理数据,二者并行运行。
  2. 匿名函数与channel:生产者匿名函数通过ch <- i将生成的数据发送到channel,消费者匿名函数通过for num := range ch从channel接收数据。channel作为数据传递的桥梁,连接了生产者和消费者。

可能遇到的同步问题及解决办法

  1. 死锁
    • 问题:如果在生产者未向channel发送数据前,消费者先尝试从channel接收数据,或者在生产者未关闭channel的情况下主函数退出,都可能导致死锁。
    • 解决办法:在生产者完成数据发送后,及时关闭channel,如上述代码中close(ch)。消费者使用for... range循环从channel接收数据,这样当channel关闭时,循环会自动结束,避免死锁。
  2. 数据竞争
    • 问题:由于生产者和消费者是并发执行的,如果多个goroutine同时访问和修改共享资源(这里主要是channel),可能会引发数据竞争。
    • 解决办法:在Go语言中,channel本身是线程安全的,所以在这个简单的生产者 - 消费者模型中,通过channel传递数据可以避免数据竞争问题。不需要额外的同步机制如互斥锁等来保护对channel的操作。