Go 如何停止在封闭通道上接收值?
我在API请求后执行了以下类似的代码。 当API调用执行时,如果我得到一个SIGINT,我想做一些清理活动。如果我没有收到任何信号,那么我想使用Go 如何停止在封闭通道上接收值?,go,Go,我在API请求后执行了以下类似的代码。 当API调用执行时,如果我得到一个SIGINT,我想做一些清理活动。如果我没有收到任何信号,那么我想使用done通道关闭sigs通道 但即使这样做了,当我使用Ctrl+C停止服务器时。它恐慌的意思是“恐慌:通过封闭频道发送” package main import ( "fmt" "time" "os" "os/signal" &quo
done
通道关闭sigs
通道
但即使这样做了,当我使用Ctrl+C
停止服务器时。它恐慌的意思是“恐慌:通过封闭频道发送”
package main
import (
"fmt"
"time"
"os"
"os/signal"
"syscall"
)
func main() {
fmt.Println("Hello, playground")
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
done := make(chan bool, 1)
go func() {
for {
select {
case val, ok := <-sigs:
if !ok {
return
}
fmt.Println("Hello", val, ok)
case <-done:
close(sigs)
return
}
}
}()
done <- true
time.Sleep(2 * time.Second)
}
这里发生的情况是,您关闭了
sig
频道,然后当您按下Ctrl+C
时,会出现SIGINT
,然后go运行时尝试推送到sig
频道,但它已关闭。因此,很自然地会发生恐慌。我相信你永远不应该关闭
sig
频道。你不需要关闭sig
。所以没问题。是的,我需要关闭它。但即使在关闭之后,它仍然在接收。“如何停止在关闭的通道上接收值?”这是绝对不可能的。你所能做的就是不要在封闭的频道上发送。但那是一件完全不同的事情。为什么你认为你需要关闭sigs
?@CriticalRebel一旦你的程序终止,“保持它打开”可能会消耗哪些“资源”?重复icza告诉您的内容:“您不需要关闭sigs。因此没有问题。”但正因为如此,它持有一个API请求。@CriticalRebel我认为这不是您的问题。你所说的“它持有一个API请求”是什么意思?@super-Ok-my-bad。它实际上并没有保存API。我在每个API请求之后执行此代码。我只想退出此goroutine,在成功关闭sigs通道后再也不会收到任何信号。@CriticalRebel然后返回。无需关闭sig
。通过返回,您将退出goroutine。感谢您的回答:)尽管我发现了不同的解决方案
case _, ok := <-sigs :
if !ok {
// after closing channel
signal.Stop(sigs)
return
}
// if any signal is received
os.Exit(0)