Golang 如何处理信号
在讨论 信号 和如何处理它们之前,让我们先谈谈创建 信号 的常见情况 。 信号 可以从终端传递,通过 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中处理这些信号和处理它们。
为了优雅地处理这些信号,我们可以使用一个 通道 ,它的类型是 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