附加的要点是一个使用生产者/多消费者模型中的渠道的简单程序。出于某种原因,
go run channels.go
打印所有结果但不返回(并且没有死锁或至少不会让我发生死锁的恐慌。)
type walkietalkie struct {
in chan int
out chan int
quit chan bool
}
var items []int = []int{
0, 1, 2, 3, 4, 5,
}
func work1(q walkietalkie) {
for {
select {
case a, more := <- q.in:
if more {
q.out <- a * 2
}
default:
break
}
}
}
func work2(q walkietalkie) {
for {
select {
case a, more := <- q.in:
if more {
q.out <- a * -1
}
default:
break
}
}
}
func work3(q walkietalkie) {
for {
select {
case a, more := <- q.in:
if more {
q.out <- a * 7
}
default:
break
}
}
}
func main() {
results := make(chan int, 18)
defer close(results)
w := []walkietalkie{
walkietalkie{ in: make(chan int, 6), out: results, quit: make(chan bool, 1) },
walkietalkie{ in: make(chan int, 6), out: results, quit: make(chan bool, 1) },
walkietalkie{ in: make(chan int, 6), out: results, quit: make(chan bool, 1) },
}
go work1(w[0])
go work2(w[1])
go work3(w[2])
// Iterate over work items
l := len(items)
for i, e := range items {
// Send the work item to each worker
for _, f := range w {
f.in <- e // send the work item
if i == l - 1 { // This is the last input, close the channel
close(f.in)
}
}
}
// Read all the results from the workers
for {
select {
case r, more := <-results:
if more {
fmt.Println(r)
} else {
continue
}
default:
break
}
}
}
答案 0 :(得分:6)
你有一些问题。
对于1,从具有多个返回值的通道读取,如
case a, more := <-q.in
将继续关闭通道,将更多设置为false。在您的情况下,default
永远不会被击中。
但是这些都是goroutines,并不会阻止程序退出。问题是你的主要goroutine正在做同样的事情。而且,事实证明,break
将打破选择以及循环。因此,如果您想要打破for循环,则需要使用标签break LABEL。
作为替代方案,您也可以返回而不是破坏主要的goroutine。