Bootstrap

【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() 或其他方式来标记测试失败。

💪无人扶我青云志,我自踏雪至山巅。
在这里插入图片描述

;