【发布时间】:2017-09-08 21:39:26
【问题描述】:
我正在尝试在 Go 中实现停止循环。 我现在拥有的代码的灵感来自这里: how to kill goroutine
但是,我无法让我的代码按预期运行。我的复杂代码库中的代码的简化版本是这样的:
package main
import (
"fmt"
"time"
)
var quit chan struct{}
var send chan int
func quitroutine() {
for {
select {
case cnt := <-send:
fmt.Println(cnt)
if cnt == 5 {
quit <- struct{}{}
}
}
}
}
func runLoop() {
cnt := 0
for {
select {
case <-quit:
fmt.Println("quit!")
default:
fmt.Println("default")
}
fmt.Println("inloop")
time.Sleep(1 * time.Second)
cnt++
send <- cnt
}
}
func main() {
quit = make(chan struct{})
send = make(chan int)
go quitroutine()
runLoop()
fmt.Println("terminated")
}
此代码崩溃:
default
inloop
5
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan send]:
main.runLoop()
/tmp/t.go:37 +0x1a6
main.main()
/tmp/t.go:45 +0xa4
goroutine 5 [chan send]:
main.quitroutine()
/tmp/t.go:18 +0x10e
created by main.main
/tmp/t.go:44 +0x9f
exit status 2
问题:
为什么在
cnt为 5 之后它会崩溃?如果cnt == 5,quitroutine仅写入quitchannel,但不会自行终止。而runLoop,如果它在quit频道上接收,应该只打印“退出!” (它不会),但不会自行终止。为什么我没有得到“退出!”输出?我还能得到
quit频道吗?这需要如何正确实现
【问题讨论】:
-
你不是任何
break或return语句,这会让你摆脱循环。 -
@Flimzy 在
main(),我正在执行go quitroutine()。我的假设是在quitroutine()我维护一个计数器,当计数器达到5时,它发送到quit以停止runLoop(),然后将终止整个程序。 -
@RayfenWindspear 我之前在
quit的情况下有return(和break),但出于调试目的我删除了它