gpt4 book ai didi

Go 程序不会死锁但也不会返回

转载 作者:IT王子 更新时间:2023-10-29 02:26:14 24 4
gpt4 key购买 nike

附件中的要点是一个在生产者/多消费者模型中使用 channel 的简单程序。出于某种原因,

go run channels.go 打印所有结果但不返回(并且不会死锁或者至少 go 不会让我 panic 发生死锁。)

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
}
}

}

最佳答案

你有几个问题。

对于 1,从具有多个返回值的 channel 读取,例如

case a, more := <-q.in 

将在关闭的 channel 上继续,更多设置为 false。在您的情况下,default 永远不会被命中。

但是那些在 goroutines 中并且不会阻止程序退出。问题是你的主要 goroutine 正在做同样的事情。此外,事实证明,break 将跳出选择和 for 循环。所以如果你想打破 for 循环,那么你需要使用标签和 break LABEL .

作为替代方案,您也可以只返回而不是中断主 goroutine。

关于Go 程序不会死锁但也不会返回,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49566455/

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