我希望在两个频道上进行go例程侦听,两个频道都排空时将其阻塞。但是,如果两个通道都包含数据,我希望先清空一个通道,再处理另一个通道。
在下面的工作示例中,我希望out在exit处理所有内容之前先将其清空。我使用的select-statement没有任何优先顺序。我如何解决这个问题,使所有10个超值都在出口之前得到处理?
out
exit
select
package main import "fmt" func sender(out chan int, exit chan bool){ for i := 1; i <= 10; i++ { out <- i } exit <- true } func main(){ out := make(chan int, 10) exit := make(chan bool) go sender(out, exit) L: for { select { case i := <-out: fmt.Printf("Value: %d\n", i) case <-exit: fmt.Println("Exiting") break L } } fmt.Println("Did we get all 10? Most likely not") }
package main import "fmt" func sender(out chan int, exit chan bool) { for i := 1; i <= 10; i++ { out <- i } exit <- true } func main() { out := make(chan int, 10) exit := make(chan bool) go sender(out, exit) for { select { case i := <-out: fmt.Printf("Value: %d\n", i) continue default: } select { case i := <-out: fmt.Printf("Value: %d\n", i) continue case <-exit: fmt.Println("Exiting") } break } fmt.Println("Did we get all 10? I think so!") }
第一次选择的默认情况使其变为非阻塞。该选择将耗尽输出通道,而无需查看出口通道,否则将不等待。如果输出通道为空,则立即下降到第二选择。第二个选择是阻止。它将等待任一通道上的数据。如果有出口,它将对其进行处理并允许循环退出。如果有数据,它将返回循环的顶部并返回到耗尽模式。