MST

星途 面试题库

面试题:Go语言中利用通道实现简单并发控制的案例分析

假设有一个任务列表,每个任务是计算一个整数的平方。请用Go语言编写代码,使用goroutine和通道来并发执行这些任务,并最终收集所有任务的结果。请分析代码中是如何通过通道实现并发控制的,例如如何保证任务的有序执行或如何避免数据竞争。
47.0万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
package main

import (
    "fmt"
)

func squareTask(num int, resultChan chan int) {
    result := num * num
    resultChan <- result
}

func main() {
    tasks := []int{1, 2, 3, 4, 5}
    resultChan := make(chan int, len(tasks))

    for _, task := range tasks {
        go squareTask(task, resultChan)
    }

    var results []int
    for i := 0; i < len(tasks); i++ {
        results = append(results, <-resultChan)
    }
    close(resultChan)

    fmt.Println("Results:", results)
}

通道实现并发控制分析

  1. 任务执行:每个任务通过 go squareTask(task, resultChan) 开启一个 goroutine 并发执行。squareTask 函数计算整数的平方,并将结果发送到 resultChan 通道。
  2. 数据收集:主 goroutine 通过 for 循环从 resultChan 通道读取结果,并将其追加到 results 切片中。由于 for 循环的读取顺序,这里并不能保证任务的有序执行。如果要保证有序执行,可以使用带缓冲通道并按任务发送顺序读取,或者使用另一个通道来跟踪任务完成顺序。
  3. 避免数据竞争:这里通过通道进行数据传递,goroutine 之间不直接共享内存,而是通过通道发送和接收数据。通道本身是线程安全的,因此避免了数据竞争问题。同时,在所有数据读取完毕后,通过 close(resultChan) 关闭通道,防止向已关闭通道发送数据引发运行时错误。