我想知道如何排出/关闭缓冲的通道以便我不会陷入死锁?我正在使用范围循环通道,但似乎虽然它们是“读取”但它们并没有像非缓冲通道那样关闭。
package main
func main() {
cp := 2
ch := make(chan string, cp)
for i := 0; i < cp; i++ {
go send(ch)
}
go send(ch)
for lc := range ch {
print(lc)
}
}
func send(ch chan string) {
ch <- "hello\n"
}
答案 0 :(得分:1)
您可以使用close()
builtin关闭频道。在完成所有并发处理之后,必须将其称为。你如何做到这一点取决于你想做什么。
在您当前的架构中,您似乎必须建立一个全局状态,即跟踪所有进程并确定最后一个进程完成的状态。例如,可以使用sync.WaitGroup
来实现这种状态。
func send(c chan string, wg *sync.WaitGroup) {
defer wg.Done()
// ...
}
wg := &sync.WaitGroup{}
for i := 0; i < cp; i++ {
wg.Add(1)
go send(ch, wg)
}
wg.Add(1)
go send(ch, wg)
wg.Wait()
close(ch)
for e := range(ch) {
// ...
}
请注意,关闭频道然后对其进行迭代将只为提供在频道中排队的元素。这意味着任何想要在频道中设置值的goroutine都不能在频道关闭时执行此操作。