如何在 Golang 中处理信号?
go programmingserver side programmingprogramming更新于 2025/4/10 18:22:17
在讨论信号及其处理方法之前,让我们先讨论一下创建信号的常见场景。信号可以从终端传递,方法是使用 CTRL+C 终止程序,或者我们可以默认调用 os 包为我们提供的 Exit() 函数。
示例 1
让我们考虑一个例子,我们将在已延迟的函数声明之后立即调用 os.Exit() 函数。
考虑下面显示的代码。
package main import ( "fmt" "os" "time" ) func main() { defer func() { fmt.Println("Inside the deferred function()") }() fmt.Println("Inside the main function") time.Sleep(1 * time.Second) os.Exit(1) }
在上面的代码中,我们调用了 os.Exit() 函数,该函数不会为延迟的匿名函数提供执行的机会,因为程序将退出。
输出
如果我们使用命令 go run main.go 运行上面的代码,那么我们将在终端中获得以下输出。
Inside the main function Program exited: status 1.
我们可能得到的另一个信号是,我们借助 CTRL+C 终止进程。
如何在 Golang 中处理信号
我们确实讨论了将信号传递给程序的不同方式。现在,让我们讨论如何处理这些信号并在 Go 中处理它们。
为了优雅地处理这些信号,我们可以使用 channel,其类型为 os.Signal,本质上是阻塞的。然后我们将使用 Notify() 函数,在该函数中我们可以传递我们期望的不同类型的信号,例如 os.Interrupt 和 syscall.SIGTERM。
示例 2
考虑下面显示的代码。
package main import ( "fmt" "os" "os/signal" "syscall" ) func main() { sigChannel := make(chan os.Signal, 1) signal.Notify(sigChannel, os.Interrupt, syscall.SIGTERM) fmt.Println("Try pressing CTRL + C to handle the interrupt") select { case <-sigChannel: fmt.Println("The interrupt got handled") os.Exit(0) } }
在上面的代码中,我们创建了一个容量为 1 的缓冲通道,然后调用 Notify() 函数。
输出
如果我们使用命令 go run main.go 运行上面的代码,然后按 CTRL + C,那么我们将在终端中获得以下输出。
Try pressing CTRL + C to handle the interrupt The interrupt got handled