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

ove*_*nge 9 go goroutine

在下面的代码中:

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")
}
Run Code Online (Sandbox Code Playgroud)

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

无缓冲通道提供交付保证。

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


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

Die*_*Epp 16

来自signal.Notify 文档

\n
\n

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

\n
\n

所以,回答你的问题:

\n
\n

无缓冲通道提供交付保证。

\n
\n

这是不正确的。只有了解发送者和接收者的行为,才能保证递送。

\n

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

\n
\n

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

\n
\n

通道中没有\xe2\x80\x9cdelay\xe2\x80\x9d。缓冲区就是通道中可以存储多少个项目。

\n
\n

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

\n
\n

该代码可能会工作,但不能保证一定能工作。问题是您不知道\xe2\x80\x99 何时执行此行:

\n
sig := <-sigs\n
Run Code Online (Sandbox Code Playgroud)\n

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

\n

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

\n

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

\n

  • @overexchange https://cs.opensource.google/go/go/+/refs/tags/go1.16.6:src/os/signal/signal.go;l=232 (2认同)