package main
import (
"fmt"
)
func main() {
aChan := make(chan int)
bChan := make(chan int)
cChan := make(chan int)
go taskA(aChan)
go taskB(aChan, bChan)
go taskC(bChan, cChan)
resultC := <-cChan
fmt.Println("最终结果:", resultC)
close(aChan)
close(bChan)
close(cChan)
}
func taskA(out chan<- int) {
// 模拟任务A的计算
result := 10
out <- result
close(out)
}
func taskB(in <-chan int, out chan<- int) {
data := <-in
// 模拟任务B依赖任务A结果的计算
result := data * 2
out <- result
close(out)
}
func taskC(in <-chan int, out chan<- int) {
data := <-in
// 模拟任务C依赖任务B结果的计算
result := data + 5
out <- result
close(out)
}
避免死锁的方法
- 确保所有通道都有发送者和接收者:在上述代码中,每个通道都有对应的发送和接收操作,避免因通道操作不匹配导致死锁。例如,
taskA
向 aChan
发送数据,taskB
从 aChan
接收数据。
- 及时关闭通道:在每个任务完成发送数据后,及时关闭通道。如
taskA
、taskB
和 taskC
完成计算并发送数据后,都调用 close
关闭通道。这可以防止接收者在通道关闭且无数据时永远阻塞。
- 合理安排Goroutine的启动顺序:在
main
函数中,按照任务依赖顺序启动 Goroutine
,确保依赖在前的任务先执行。同时,main
函数中最后从 cChan
接收数据,避免 main
函数提前退出导致其他 Goroutine
未完成就结束程序。