gpt4 book ai didi

常规处理 channel 范围

转载 作者:IT王子 更新时间:2023-10-29 01:56:42 25 4
gpt4 key购买 nike

我已经在 Golang 工作了很长时间。但是,尽管我知道解决问题的方法,但我仍然面临这个问题。但从来没有弄清楚为什么会这样。

例如,如果我有如下入站和出站 channel 的管道情况:

package main

import (
"fmt"
)

func main() {
for n := range sq(sq(gen(3, 4))) {
fmt.Println(n)
}
fmt.Println("Process completed")
}

func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}

func sq(in <-chan int) <-chan int {
out := make(chan int)
go func() {
for n := range in {
out <- n * n
}
close(out)
}()
return out
}

它不会给我带来死锁情况。但是,如果我删除出站代码中的 go 例程,如下所示:

func sq(in <-chan int) <-chan int {
out := make(chan int)
for n := range in {
out <- n * n
}
close(out)
return out
}

我收到死锁错误。为什么在不使用 go 例程的情况下使用 range 循环 channel 会导致死锁。

最佳答案

这种情况是sq函数的输出 channel 没有缓冲造成的。所以 sq 正在等待下一个函数从输出中读取,但是如果 sq 不是异步的,它就不会发生 ( Playground link ):

package main

import (
"fmt"
"sync"
)

var wg sync.WaitGroup

func main() {
numsCh := gen(3, 4)
sqCh := sq(numsCh) // if there is no sq in body - we are locked here until input channel will be closed
result := sq(sqCh) // but if output channel is not buffered, so `sq` is locked, until next function will read from output channel

for n := range result {
fmt.Println(n)
}
fmt.Println("Process completed")
}

func gen(nums ...int) <-chan int {
out := make(chan int)
go func() {
for _, n := range nums {
out <- n
}
close(out)
}()
return out
}

func sq(in <-chan int) <-chan int {
out := make(chan int, 100)
for n := range in {
out <- n * n
}
close(out)
return out
}

关于常规处理 channel 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52943450/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com