MST

星途 面试题库

面试题:Go闭包与通道在并发编程中的协作机制

详细描述Go闭包和通道在并发编程中是如何协作来保证数据的有序处理和避免竞态条件的。请通过编写一个具体的示例代码来展示这种协作机制,示例需包含至少三个不同功能的goroutine通过闭包和通道协同工作。
10.9万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

在Go语言中,闭包可以捕获其周围环境的变量,而通道用于在goroutine之间进行通信和同步。通过合理使用闭包和通道,可以保证数据的有序处理并避免竞态条件。

以下是一个示例代码,展示了三个不同功能的goroutine如何通过闭包和通道协同工作:

package main

import (
    "fmt"
)

// 生成器函数,生成一系列数字
func generator(ch chan<- int) {
    for i := 1; i <= 10; i++ {
        ch <- i
    }
    close(ch)
}

// 平方计算函数
func squarer(in <-chan int, out chan<- int) {
    for num := range in {
        out <- num * num
    }
    close(out)
}

// 打印函数
func printer(in <-chan int) {
    for num := range in {
        fmt.Println(num)
    }
}

func main() {
    ch1 := make(chan int)
    ch2 := make(chan int)

    // 启动生成器goroutine
    go generator(ch1)
    // 启动平方计算goroutine
    go squarer(ch1, ch2)
    // 启动打印goroutine
    go printer(ch2)

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

代码说明

  1. generator函数:这是一个闭包,它向通道 ch 发送数字序列 110,发送完毕后关闭通道。它只写通道 ch,所以参数是 chan<- int
  2. squarer函数:这也是一个闭包,它从输入通道 in 接收数字,计算其平方,并将结果发送到输出通道 out。当输入通道关闭时,它也关闭输出通道。这里 in 是只读通道 <-chan intout 是只写通道 chan<- int
  3. printer函数:这是一个闭包,它从通道 in 接收数字并打印出来。当通道关闭时,循环结束。它的通道 in 是只读通道 <-chan int
  4. main函数:创建了两个通道 ch1ch2,并分别启动了 generatorsquarerprinter 三个goroutine。generator 生成的数字通过 ch1 传递给 squarersquarer 计算平方后通过 ch2 传递给 printer
  5. select {}:防止主线程退出,保证所有goroutine有足够时间执行。

通过这种方式,数据在不同的goroutine之间有序传递,每个操作都在不同的goroutine中并行执行,同时避免了竞态条件,因为数据通过通道传递,而不是共享内存。