【go从零单排】Signals、Exit
🌈Don’t worry , just coding!
内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。
📗概念
在 Go 语言中,信号(signals)是操作系统用来通知进程发生某些事件的一种机制。常见的信号包括中断信号(如 Ctrl+C 产生的 SIGINT)、终止信号(SIGTERM)等。Go 提供了 os/signal 包来处理这些信号。
信号的类型:
- SIGINT:中断信号,通常由 Ctrl+C 触发。
- SIGTERM:请求程序终止的信号。
- SIGHUP:挂起信号,通常表示终端关闭。
- SIGQUIT:退出信号,通常由 Ctrl+\ 触发。
💻代码
Signals
package main
import (
//fmt:用于格式化输出。
//os:提供与操作系统交互的功能。
//os/signal:用于处理操作系统信号。
//syscall:提供系统调用的接口,包含信号常量。
"fmt"
"os"
"os/signal"
"syscall"
)
func main() {
//创建一个信道 sigs,用于接收操作系统信号。信道的缓冲区大小为 1。
sigs := make(chan os.Signal, 1)
//通过 signal.Notify 函数,注册 sigs 信道以接收 SIGINT(通常由 Ctrl+C 触发)和 SIGTERM(终止信号)这两种信号。
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
//创建另一个信道 done,用于指示信号处理是否完成。
done := make(chan bool, 1)
//启动一个新的 goroutine(轻量级线程)。
go func() {
//在 goroutine 中,等待从 sigs 信道接收信号。
sig := <-sigs
//当接收到信号时,打印一个空行和接收到的信号。
fmt.Println()
fmt.Println(sig)
//将 true 发送到 done 信道,表示信号处理已完成。
done <- true
}() //结束 goroutine 的定义。
fmt.Println("awaiting signal")
<-done //主 goroutine 在这里阻塞,直到从 done 信道接收到信号,表示信号处理完成。
fmt.Println("exiting") //打印退出消息,表示程序即将结束。
}
Exit
在 Go 语言中,os.Exit 是一个用于终止程序的函数。它可以立即停止程序的执行,并返回指定的状态码给操作系统。
package main
import (
//fmt:用于格式化输出。
//os:提供与操作系统交互的功能,包括退出程序的功能。
"fmt"
"os"
)
func main() {
//使用 defer 关键字,这行代码会在 main 函数结束时执行。
//通常,defer 用于确保在函数返回时执行某些清理操作或输出。在这里,它会在 main 函数结束时打印一个感叹号 !。
defer fmt.Println("!")
//调用 os.Exit(3) 函数直接退出程序,并返回状态码 3。
//重要的是,os.Exit 会立即终止程序的执行,不会执行任何后续的代码,包括 defer 语句。
os.Exit(3)
}
🔍理解
singal
- 信号处理的并发性:信号处理程序是异步的,可能会在主程序执行时被触发。
- 优雅退出:通常在接收到信号时,程序会进行一些清理工作(如关闭文件、释放资源等),以确保优雅退出。
Exit
- 调用 os.Exit 会立即终止当前程序的执行,不会执行任何后续的代码,包括 defer 语句。这一点与其他语言(如 C)类似。
- 状态码 0:表示程序成功完成,没有错误。
- 非零状态码:表示程序遇到错误或异常,通常用于指示不同的错误类型。
💡 Tips小知识点
- 在测试或其他环境中,使用 os.Exit 可能会导致测试框架无法正确捕获测试结果。因此,在测试代码中应避免使用 os.Exit,而是使用 t.Fail() 或其他方式来标记测试失败。
💪无人扶我青云志,我自踏雪至山巅。