可以使用非缓冲通道接收信号吗?



在下面的代码中:

package main
import (
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
sigs := make(chan os.Signal, 1)
done := make(chan bool, 1)
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
go func() {
sig := <-sigs
fmt.Println()
fmt.Println(sig)
done <- true
}()
fmt.Println("awaiting signal")
<-done
fmt.Println("exiting")
}

用于接收信号的缓冲通道大小。

无缓冲通道提供传输保障。

一个缓冲通道的大小提供延迟保证


我们可以在这种情况下使用非缓冲通道吗?sigs := make(chan os.Signal)

来自信号。通知文档

包信号不会阻塞发送到c:调用者必须确保c有足够的缓冲空间来跟上预期的信号速率。对于仅用于通知一个信号值的通道,大小为1的缓冲区就足够了。

那么,回答你的问题:

无缓冲通道提供传输保障。

这是不正确的。只有知道发送方和接收方的行为,才能保证发送。

在这种情况下,发送方是非阻塞的。因此,如果接收方没有等待信号,消息将被丢弃。

大小一个缓冲通道提供延迟保证

通道中没有"延迟"。缓冲区就是通道中可以存储多少项。

我们可以在这种情况下使用非缓冲通道吗?

代码将可能工作,但它不能保证工作。问题是您不知道这一行何时执行:
sig := <-sigs

signal.Notify之后但在<-sigs之前到达的任何信号将被丢弃(如果通道未缓冲)。请记住,signal.Notify是非阻塞的——这仅仅意味着它将放弃而不是等待。

如果你不希望信号被丢弃,使用缓冲通道。

当然,这种情况不太可能发生。但这在技术上是可行的。

最新更新