场景一:任务分发与结果收集
- 场景描述:有多个相同类型的任务需要并发处理,将任务分发给多个Goroutine,每个Goroutine处理完任务后将结果返回,最后收集所有结果。
- 代码示例:
package main
import (
"fmt"
)
func worker(id int, tasks <-chan int, results chan<- int) {
for task := range tasks {
result := task * task // 模拟任务处理,这里是计算平方
fmt.Printf("Worker %d processed task %d and got result %d\n", id, task, result)
results <- result
}
}
func main() {
numWorkers := 3
tasks := make(chan int, 10)
results := make(chan int, 10)
for i := 0; i < numWorkers; i++ {
go worker(i, tasks, results)
}
// 发送任务
for i := 1; i <= 5; i++ {
tasks <- i
}
close(tasks)
// 收集结果
var finalResults []int
for i := 0; i < 5; i++ {
finalResults = append(finalResults, <-results)
}
close(results)
fmt.Println("Final results:", finalResults)
}
- 解释:
worker
函数从tasks
通道接收任务,处理后将结果发送到results
通道。main
函数中创建多个worker
Goroutine,然后向tasks
通道发送任务,最后从results
通道收集结果。
场景二:流水线处理
- 场景描述:任务处理需要多个步骤,每个步骤由不同的Goroutine负责,数据像流水线一样依次经过各个步骤处理。
- 代码示例:
package main
import (
"fmt"
)
func step1(input <-chan int, output chan<- int) {
for data := range input {
result := data + 1 // 模拟第一步处理
output <- result
}
close(output)
}
func step2(input <-chan int, output chan<- int) {
for data := range input {
result := data * 2 // 模拟第二步处理
output <- result
}
close(output)
}
func main() {
data := make(chan int, 10)
step1Output := make(chan int, 10)
finalOutput := make(chan int, 10)
go step1(data, step1Output)
go step2(step1Output, finalOutput)
// 发送初始数据
for i := 1; i <= 3; i++ {
data <- i
}
close(data)
// 收集最终结果
for result := range finalOutput {
fmt.Println("Final result:", result)
}
}
- 解释:
step1
函数从data
通道接收数据,处理后发送到step1Output
通道。step2
函数从step1Output
通道接收数据,再次处理后发送到finalOutput
通道。main
函数创建两个步骤的Goroutine,并发送初始数据,最后收集最终结果。