Golang如何优雅的退出程序

Golang如何优雅的退出程序

在 Go 中优雅地退出程序,通常需要处理一些清理工作,如关闭文件、网络连接、释放资源等。以下是一些常见的方法:

一、使用 os.Signal 和 signal.Notify

  1. 捕获系统信号:可以使用 os/signal 包来捕获中断信号(如 SIGINT 或 SIGTERM)并执行清理工作。
  2. 实现清理逻辑:在接收到信号时执行必要的清理操作。

以下是一个简单的示例:

go 复制代码
package main

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	// 创建一个通道来接收信号
	sigs := make(chan os.Signal, 1)

	// 注册要接收的信号
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	// 创建一个通道来指示退出
	done := make(chan bool, 1)

	// 启动一个 goroutine 来处理信号
	go func() {
		sig := <-sigs
		fmt.Println()
		fmt.Println("收到信号:", sig)
		// 执行清理工作
		cleanup()
		// 通知主 goroutine 可以退出了
		done <- true
	}()

	fmt.Println("等待信号...")
	// 主 goroutine 等待退出信号
	<-done
	fmt.Println("程序退出")
}

func cleanup() {
	fmt.Println("执行清理工作...")
	// 在这里添加清理逻辑
	time.Sleep(2 * time.Second) // 模拟清理工作
	fmt.Println("清理完成")
}

二、使用 context.Context

在需要控制多个 goroutine 的情况下,使用 context.Context 可以更方便地管理他们的生命周期。

go 复制代码
package main

import (
	"context"
	"fmt"
	"os"
	"os/signal"
	"syscall"
	"time"
)

func main() {
	ctx, cancel := context.WithCancel(context.Background())

	// 捕获信号
	sigs := make(chan os.Signal, 1)
	signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)

	go func() {
		<-sigs
		fmt.Println("\n收到退出信号")
		cancel() // 取消 context,通知所有 goroutine 停止
	}()

	// 启动一些需要管理生命周期的 goroutine
	go worker(ctx, "worker1")
	go worker(ctx, "worker2")

	// 阻塞,直到 context 被取消
	<-ctx.Done()
	fmt.Println("程序退出")
}

func worker(ctx context.Context, name string) {
	for {
		select {
		case <-ctx.Done():
			fmt.Printf("%s 停止\n", name)
			return
		default:
			fmt.Printf("%s 工作中\n", name)
			time.Sleep(1 * time.Second)
		}
	}
}

通过这些方法,可以确保在接收到退出信号时,程序能够优雅地关闭并释放所有资源。

相关推荐
晨曦中的暮雨1 小时前
限流算法——固定窗口、滑动窗口、漏桶、令牌桶
java·开发语言·算法
喵了几个咪2 小时前
GoWind CMS 拆解:在 Go 里给 TipTap 搭一套 Yjs 协同后端
开发语言·后端·golang
程序员清风2 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
2601_962885724 小时前
如何用 Python 把 K 线重采样成任意周期?
开发语言·python
Wang's Blog4 小时前
Java 项目实战: 交友项目 - 圈子功能实现:总结
java·开发语言·交友
下一站春风里5 小时前
位运算完整学习笔记:按位与(&)+ 异或(^)
开发语言·c++·算法
天外飞雨道沧桑6 小时前
我在浏览器里练了一个 792 参数的大模型,它学会了补全 JavaScript
开发语言·javascript·ai·ecmascript·ai编程
hhhjhl6 小时前
Yup 跨端三方库仓颉适配全流程
java·开发语言
运维行者_6 小时前
网络监控工具怎么选?从设备监控到智能运维的能力清单
运维·服务器·开发语言·网络·人工智能·支持向量机·php
“AI国潮设计-小江”7 小时前
【AIGC实战】Python+SDXL打造“潮汕英歌舞IP”万能立牌插件,批量生成“发财元宝蛋糕”视觉营销方案(附源码)
开发语言·人工智能·python·prompt·aigc