0

0

聊聊golang的优雅关闭方式

PHPz

PHPz

发布时间:2023-04-27 09:11:06

|

1706人浏览过

|

来源于php中文网

原创

在开发使用golang的时候,一般都会遇到需要关闭或停止运行的情况。比如,程序运行结束或者出现异常,这时需要优雅地关闭。

优雅关闭可以让程序停止运行的同时,能够让已经启动的任务处理完毕,避免数据丢失和资源泄漏等问题,也不会对客户端造成不必要的损失。本文就讨论一下golang的优雅关闭方式。

优雅关闭方法

在golang中,优雅关闭的实现不难,我们可以通过设置信号量或者channel的方式进行,具体的实现方法如下:

通过信号量实现

package main

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

func main() {
    stop := make(chan os.Signal, 1)
    signal.Notify(stop, syscall.SIGINT, syscall.SIGTERM)

    log.Println("Starting...")

    go func() {
        <-stop
        log.Println("Stopping...")

        // 处理关闭逻辑
        time.Sleep(3 * time.Second)

        log.Println("Graceful shutdown finished")
        os.Exit(0)
    }()

    // 处理业务逻辑
    for {
        log.Println("Running...")
        time.Sleep(1 * time.Second)
    }
}

这段代码中通过make创建了一个类型为os.Signal,长度为1的信号缓冲channel,然后通过signal包中的Notify函数告诉操作系统,我们想要监听的信号是SIGINT和SIGTERM,这两个信号都可以代表程序的关闭请求。

接着,我们启动了一个goroutine,监听stop这个channel,一旦接受到SIGINT或SIGTERM信号,就会触发这个goroutine的执行。在执行过程中,我们处理关闭逻辑,这里用了time.Sleep模拟了一个比较耗时的操作,以便更好的测试我们的程序是否正常结束。最后通过os.Exit函数通知操作系统程序关闭请求已经处理完毕了。

立即学习go语言免费学习笔记(深入)”;

在主goroutine中,我们处理了业务逻辑,每秒钟打印一次"Running...",这里只是一个简单的示例;通常情况下,我们在处理业务逻辑时,需要定时保存数据和释放资源等。

通过channel实现

package main

import (
    "log"
    "os"
    "time"
)

func main() {
    done := make(chan bool)

    log.Println("Starting...")

    go func() {
        osSignals := make(chan os.Signal, 1)
        signal.Notify(osSignals, syscall.SIGINT, syscall.SIGTERM)

        select {
        case <-osSignals:
            log.Println("Stopping...")

            // 处理关闭逻辑
            time.Sleep(3 * time.Second)

            log.Println("Graceful shutdown finished")
            done <- true
        }
    }()

    // 处理业务逻辑
    for {
        log.Println("Running...")
        time.Sleep(1 * time.Second)
        select {
        case <-done:
            return // 正常退出
        default:
            continue
        }
    }
}

这段代码中,我们创建了一个bool类型的done变量,表示我们的程序是否已经完成,然后在主goroutine中处理业务逻辑,定时打印"Running...",并通过select函数监听done。如果done变量被设为true,程序就结束运行,返回到main函数中,完成程序退出工作。

LobeHub
LobeHub

LobeChat brings you the best user experience of ChatGPT, OLLaMA, Gemini, Claude

下载

在另外一个goroutine中,我们通过make创建了一个类型为os.Signal,长度为1的信号缓冲channel,然后通过signal包中的Notify函数告诉操作系统,我们想要监听的信号是SIGINT和SIGTERM。接下来,通过select函数监听osSignals,如果接收到SIGINT或SIGTERM信号,就会触发特定操作。

程序监听的信号

在Linux系统中,一般有以下几种信号:

信号名称 信号描述
SIGINT 终端中断字符,通常通过 Control+C 发出
SIGTERM 终止信号,通常用来请求程序自行停止运行
SIGHUP 挂起信号,通常表示某个终端连接已经中断,需要重新读取配置文件等
SIGUSR1-31 自定义信号
SIGKILL 杀死进程信号,无法被捕捉或忽略,只能暴力杀死进程
SIGSTOP 停止进程信号,无法被捕捉或忽略,只能暴力停止进程
SIGCONT 继续运行进程
SIGPIPE 管道破裂信号,通常表示读取数据时对方已经关闭了连接
SIGALRM 闹钟信号,用来定时触发某个操作
SIGCHLD 子进程结束信号

通常情况下,我们只需要监听SIGINT和SIGTERM信号即可。

优雅关闭的作用

通过优雅关闭,我们可以避免因未能处理完毕的请求和操作而导致的数据丢失、资源泄漏等问题,对于长时间运行的程序和提供服务的应用程序尤其重要。特别是在分布式系统和微服务架构中,优雅关闭能够有效保证系统稳定性和性能,如果没有针对性的问题处理函数,程序在接到停止信号后,可能会武断的结束或触发崩溃,给客户端造成困惑甚至不必要的损失。

总结

通过本文,我们学习到了如何使用golang的channel和os/signal包进行优雅关闭,以及通过监听信号来完成优雅关闭的操作。在实际开发中,应用程序的正常关闭是一项非常重要的任务,通过优雅关闭能够有效提高程序的稳定性,避免资源浪费和数据丢失等问题。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

121

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

33

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

39

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

19

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

85

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

19

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

11

2026.01.15

ppt一键生成相关合集
ppt一键生成相关合集

本专题整合了ppt一键生成相关教程汇总,阅读专题下面的的文章了解更多详细内容。

47

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号