gpt4 book ai didi

go - 停止循环的代码不起作用

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

我正在尝试在 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

问题:

  1. 为什么在 cnt 为 5 后它会崩溃? quitroutine 仅在 cnt == 5 时写入 quit channel ,但不会自行终止。当 runLoop 时,如果它在 quit channel 上接收到,应该只打印“quit!” (它不会),但不会自行终止。

  2. 为什么我没有得到“退出!”输出?我什至可以获得 quit channel 吗?

  3. 这需要如何正确实现

最佳答案

正如 Adrian 所说,您的一个 goroutine 正在尝试发送 quit ,而另一个试图发送 send .回答您的问题:

  1. cnt == 5 quitroutine开始尝试发送 quit .因为quit <- struct{}{}不是 select在这种情况下,goroutine 将阻塞直到另一个尝试从 quit 读取.另一个 goroutine 同样被困在试图做 send <- cnt 的过程中。 (当 cnt = 6 时)。

  2. 你永远不会得到“退出!”输出是因为那个 goroutine 被卡住了试图做 send <-cnt .

  3. 我看到的最简单的解决方案是调整 runLoop()这样 send <- cntselect中的一个案例.

我会改变 runLoop()看起来像这样:

func runLoop() {
cnt := 0
for {
select {
case <-quit:
fmt.Println("quit!")
case send <- cnt: // moved stuff here
fmt.Println("inloop")
time.Sleep(1 * time.Second)
cnt++
default:
fmt.Println("default")
}
// stuff used to be here
}
}

这给了我输出(直到我终止程序):

default
inloop
0
inloop
1
inloop
2
inloop
3
inloop
4
inloop
5
quit!
default
inloop
6
inloop
7

这似乎主要是您所追求的。

我还想指出 select阻止 quitroutine()是不必要的,因为它只有一种情况。清理它可能会更清楚地表明 goroutine 在尝试发送时卡住了,并且永远不会从 send 中获取输入。 channel 。

关于go - 停止循环的代码不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46103456/

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