一个通道内的信号如何在另一个通道内一起工作?



我最近开始学习go,并试图了解通道是如何工作的。我正在那里读一本书,他们给了这样一个例子:

有时您将使用来自系统不同部分的通道。与管道不同,您不能断言通道的行为当你正在处理的代码通过它的done通道被取消时。也就是说,你不知道你的节目被取消是否意味着你的频道阅读将被取消。出于这个原因,我们需要用select语句包装从通道读取的内容,该语句也从done通道中进行选择。这很好,但是这样做需要很容易读懂的代码,如

func orDone(done, c <-chan interface{}) <-chan interface{} {
valStream := make(chan interface{})
go func() {
defer close(valStream)
for {
select {
case <-done:
return
case v, ok := <-c:
if ok == false {
return
}
select {
case valStream <- v:
case <-done:
fmt.Println("inside", count)
}
}
}
}()
return valStream
}

我不太明白通过一个完成的频道关闭一个频道是如何工作的。假设我有这样的代码:

func main() {
done1 := make(chan interface{})
done2 := make(chan interface{})
inf := infGenerator(done1)
for v := range orDone(done2, inf) {
if count == 3 {
close(done1)
}
count++
fmt.Println(v)
}
}

例如,如果第一个通道关闭,那么一切都是清楚的,它将被执行

if ok == false {
return
}

但是我不太明白当我们关闭第二个通道而不是第一个通道时,程序是如何工作的。

首先,程序进入

case <-done:
fmt.Println("inside", count)
}

然后它进入上面的那个。我不明白为什么会这样。嵌套的case <-done:不应该获取闭包消息并拾取它吗?或者如果我们关闭信道,那么它的信号不会从信道中获取?如果有可能在结束时执行另一个案例呢?

假设infGenerator关闭inf接到done信号:

关闭done1会导致关闭inf,从而导致orDone返回您所说的。

如果关闭done,函数orDone执行嵌套的done,然后执行外部的done,仅仅是因为嵌套的done没有从函数返回。它读取done信号,继续循环,循环再次读取done信号并返回。

未缓冲的通道不包含任何数据。因此,如果您关闭了一个未缓冲的通道,任何被阻塞的从该通道读取的程序都将通过false启用。任何进一步的读取尝试也将立即返回false。因此,关闭通道是向所有例程广播完成的好方法。

相关内容

最新更新