无缓冲通道可以用来接收信号吗?

Can unbuffered channel be used to receive signal?

在下面的代码中:

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)

来自signal.Notify documentation

Package signal will not block sending to c: the caller must ensure that c has sufficient buffer space to keep up with the expected signal rate. For a channel used for notification of just one signal value, a buffer of size 1 is sufficient.

所以,回答你的问题:

Unbuffered channels provide guarantee of delivery.

这是不正确的。只有了解寄件人和收件人的行为才能保证送达。

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

Size one buffered channel provides delayed guarantee

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

Can we use unbuffered channel in this scenario?

该代码可能 有效,但不保证有效。问题是你不知道这一行什么时候会被执行:

sig := <-sigs

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

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

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