当前位置: 首页 > news >正文

Go程序当父进程被kill,子进程也自动退出的问题记录

平常我们启动一个后台进程,会通过nouhp &的方式启动,这样可以在退出终端会话的时候,进程仍然可以继续在后台执行(进程的父进程id会从原来的bash进程变成1)
在go程序中,通过nouhp &的方式启动子进程,预期是即使父进程挂掉,子进程也能继续执行
但是测试过程中发现,当父进程被kill,子进程也会自动退出

首先需要了解下什么是SIGHUP和SIGTERM

1.SIGHUP(Hangup)信号通常是由终端或控制台断开时产生的信号它的作用是通知进程重新读取其配置文件,或者让进程重新初始化,以便于适应新的环境。在进程收到该信号时,一般会在日志中记录相关信息,然后进行优雅的退出或重新初始化。
2.SIGTERM(Terminate)信号是进程终止信号它通常是由kill命令发送给进程的。它的作用是请求进程正常地退出,进程在接收到该信号后,可以在清理后退出。如果进程没有处理SIGTERM信号,则可以使用kill -9命令强制杀死进程。

正常情况下,一个程序如果没有进行特别处理,那么收到SIGHUP、SIGTERM信号都会退出

通常我们在一个终端会话中启动一个进程,如果只是通过&后台启动,那么当会话关闭的时候,进程也会自动退出
这是因为会话关闭的时候,会向子进程发送SIGHUP信号,导致子进程也跟着退出
而nohup的作用就是忽略NOHUP信号,避免进程退出

go程序中可以用signal.Notify监听SIGHUP信号修改默认行为,示例代码:

package mainimport ("fmt""os""os/signal""syscall"
)func main() {// 创建一个channel用于接收信号signals := make(chan os.Signal, 1)// 注册信号signal.Notify(signals, syscall.SIGTERM, syscall.SIGHUP)// 在goroutine中等待信号go func() {for {select {case sig := <-signals:switch sig {case syscall.SIGTERM:fmt.Println("Received SIGTERM, shutting down gracefully...")// 做一些清理工作os.Exit(0)case syscall.SIGHUP:fmt.Println("Received SIGHUP, reloading configuration...")// 重新加载配置}}}}()// 主进程继续执行其他任务fmt.Println("Server started...")select {}
}

通过在子进程中用signal.Notify监听SIGHUP、SIGTERM信号,并打印日志,来进行测试(kill -1发送SIGHUP信号,kill发送SIGTERM信号)
查看日志发现,父进程被kill,子进程会收到SIGTERM信号
而nohup只是忽略SIGHUP信号,所以使用nohup启动自然就不能防止子进程退出了

解决方案是启动子进程时,修改子进程进程组id,这样子进程就不会收到SIGTERM信号了
Go示例代码:

package mainimport ("fmt""os/exec""strings""syscall"
)func main() {//这里child是上面子进程编译成的二进制程序cmd := exec.Command("/bin/bash", "-c", "./child")//SysProcAttr 字段被设置为 Setpgid 为 true,这将使子进程的进程组 ID 与其父进程不同。Pdeathsig 被设置为空信号,这意味着子进程在父进程退出时不会收到任何信号cmd.SysProcAttr = &syscall.SysProcAttr{Setpgid:   true,Pdeathsig: syscall.Signal(0),}output, err := cmd.CombinedOutput()rs := strings.TrimSpace(string(output))if err != nil {fmt.Println("Command execution failed:", err, "rs:", rs)os.Exit(1)}fmt.Println("rs:", rs)
}

ps -eo pid,ppid,pgrp,session,comm
可以通过这个命令来查看进程进程组id

还有一种情况要注意,即使不用Setpgid,使用kill -9的方式杀父进程,子进程也是不会退出的
针对一些希望父进程结束的时候,子进程也被跟着退出的场景,要么谨慎使用kill -9,要么自己做好进程退出的机制处理

参考资料:
https://blog.csdn.net/qq_34021712/article/details/115587702
https://cloud.tencent.com/developer/article/1497217
https://www.jianshu.com/p/e147d856074c%20

在这里插入图片描述

相关文章:

Go程序当父进程被kill,子进程也自动退出的问题记录

平常我们启动一个后台进程&#xff0c;会通过nouhp &的方式启动&#xff0c;这样可以在退出终端会话的时候&#xff0c;进程仍然可以继续在后台执行(进程的父进程id会从原来的bash进程变成1) 在go程序中&#xff0c;通过nouhp &的方式启动子进程&#xff0c;预期是即使…...

window10 下使用docmer-compose使用mysql镜像部署mysql

1. 在wins中找到store&#xff0c;安装Debian 2. 在桌面右键点击 linux shell窗口 3. 安装docker 4. 启动docker&#xff1a; service docker start 5. 配置加速器&#xff0c;为了拉取镜像更快&#xff0c;修改后得重新启动docker&#xff1a; vi /etc/docker/daemon.json…...

软件测试补充

软件开发的生命周期&#xff1a;需求-计划-设计-开发编码-测试-运行维护-上线 那我们的微信APP来进行举例: 需求:我需要你们团队做这样一个社交软件&#xff0c;能够像QQ一样实现聊天功能&#xff0c;发布说说的功能&#xff0c;能够群聊&#xff0c;可以转账 计划:计划软件…...

【算法】Tire字符串

作者&#xff1a;指针不指南吗 专栏&#xff1a;算法篇 &#x1f43e;或许会很慢&#xff0c;但是不可以停下&#x1f43e; 文章目录1.Trie的基本思想1.1什么是Trie1.2字符串条件1.3如何存储字符串1.4如何查找字符串2.Trie的代码实现2.1怎么用数组建树2.2完整代码1.Trie的基本思…...

【C++】STL——list的模拟实现

list的模拟实现 文章目录list的模拟实现一、list三个基本类的模拟实现总览二、节点类接口实现模拟实现构造函数三、迭代器类接口实现1.正向迭代器默认成员函数构造函数六种运算符重载 */->//--/!/2.反向迭代器四、list类接口实现1.默认成员函数1.1.构造函数1.2.析构函数1.3.…...

SpringBoot小区物业管理系统

文章目录 项目介绍主要功能截图:后台登录车位收费管理物业收费管理投诉信息管理保修信息管理基础信息管理数据分析部分代码展示设计总结项目获取方式🍅 作者主页:Java韩立 🍅 简介:Java领域优质创作者🏆、 简历模板、学习资料、面试题库【关注我,都给你】 🍅文末获…...

外网跨网远程控制内网计算机3种方案

远程控制&#xff0c;通俗来讲就是在自己个人电脑直接远程访问另台主机电脑桌面操作。 如何远程控制电脑&#xff1f;远程控制别人计算机的方案通常有两种&#xff0c;一种是开启电脑系统自带的远程桌面功能&#xff0c;如果涉及跨网内、外网互通可以同时用快解析内网映射外网&…...

记录偶发更新失败问题

一&#xff0c;代码如下Transactional(rollbackFor Exception.class) public void updateDelivery(){ // 1.新增反馈记录 // 2.更新订单状态&#xff0c;及其他字段 // 3.新增变更履历 // 4.其他新增逻辑及与其他系统交互逻辑 }二&#xff0c;问题偶尔出现&#xff08;概率极低…...

AI环境搭建步骤(Windows环境)

1. 安装好Anaconda3版本(1) 安装链接&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?CM&OD本文使用Anaconda3下载链接&#xff1a;Anaconda5(2) 注意安装anaconda时一定要把环境变量加入windows环境中。要没有勾选&#xff0c;安装完后还有手动加入…...

Linux系统之history命令的基本使用

Linux系统之history命令的基本使用一、history命令介绍二、本地环境检查1本地系统版本2.检查操作系统的内核版本三、history的命令帮助四、history命令的基本帮助1.查看所有历史执行命令2.指定历史命令条数3.清除历史命令记录4.引用历史命令5.将历史文件中的信息读入到当前缓冲…...

花7000报了培训班,3个月后我成功“骗”进了阿里,月薪拿16K....

“月薪4000元不如报名学IT&#xff0c;挑战年薪百万”这是大多数培训班在互联网上宣传的口号&#xff0c;简单的16个字却戳中了很多人的痛点&#xff0c;同龄人买车买房&#xff0c;自己却拿着微薄的工资连好一点的房子都租不起&#xff0c;这句口号 彻底激起了底层员工的焦虑&…...

Java-枚举类的使用(详解)

枚举类的使用前言一、何为枚举类&#xff1f;二、自定义枚举类&#xff08;JDK1.5之前&#xff09;1、实现1.1 属性1.2 构造器2、代码演示三、用关键字enum定义枚举类&#xff08;JDK 1.5&#xff09;1、实现1.1 属性1.2 构造器2、代码演示四、Enum类的方法五、实现接口的枚举类…...

Docker----------Docker轻量级可视化工具Portainer/监控之 CAdvisor+InfluxDB+Granfana

1.是什么 Portainer 是一款轻量级的应用&#xff0c;它提供了图形化界面&#xff0c;用于方便地管理Docker环境&#xff0c;包括单机环境和集群环境。 2 官网 官网 https://www.portainer.io/ https://docs.portainer.io/v/ce-2.9/start/install/server/docker/linux 3.…...

景嘉微7201

220112-驱动与固件-景嘉微7201驱动与固件-三期超翔TF830JM7201显卡黑屏、花屏、竖线或待机唤醒黑屏JM72系列为了让驱动和系统内核解绑&#xff0c;驱动包含核内和核外两个驱动&#xff0c;两个驱动请都务必安装&#xff1b;最近JM7201 替代R7 340 发货了&#xff0c;导致对应通…...

串口、终端应用程序 API termios

UART简介 串口全称为串行接口&#xff0c;也称为COM接口&#xff0c;串行接口指的是比特一位位顺序传输&#xff0c;通信线路简单。使用两根线就可以实现双向通信&#xff0c;一条为TX&#xff0c;一个为RX。串口通信距离远&#xff0c;但速度相对慢&#xff0c;是一种常用的工…...

【服务器搭建】教程七:如何为自己的网站添加运行时间?

前言 哈喽&#xff0c;大家好&#xff0c;我是木易巷&#xff01; 上一篇服务器搭建个人网站教程是给大家介绍了&#xff1a;网站如何添加备案号&#xff1f; 今天分享&#xff1a;如何为自己的网站添加运行时间&#xff1f; 木易巷添加网页运行时间后的效果 其实和昨天的添…...

【消息中间件】Apache Kafka 教程

文章目录Apache Kafka 概述什么是消息系统&#xff1f;点对点消息系统发布 - 订阅消息系统什么是Kafka&#xff1f;好处用例需要KafkaApache Kafka 基础&#xff08;一&#xff09;消息系统1、点对点的消息系统2、发布-订阅消息系统&#xff08;二&#xff09;Apache Kafka 简介…...

ARM基础

文章目录1.ARM成长史1.1 ARM发展的里程碑11.2 ARM发展的里程碑21.3 ARM发展的里程碑31.4 ARM发展的里程碑42.ARM的商业模式和生态系统3.先搞清楚各种版本号3.1 ARM 的型号命名问题3.2 ARM 的几种版本号3.3 ARM型号的发展历程4.SoC和CPU的区别 & 外设概念的引入4.1 SoC和CPU…...

Python排序 -- 内附蓝桥题:错误票据,奖学金

排序 ~~不定时更新&#x1f383;&#xff0c;上次更新&#xff1a;2023/02/28 &#x1f5e1;常用函数&#xff08;方法&#xff09; 1. list.sort() --> sort 是 list 的方法&#xff0c;会直接修改 list 举个栗子&#x1f330; li [2,3,1,5,4] li.sort() print(li) …...

容器化部署是什么意思?有什么优势?

多小伙伴不知道容器化部署是什么意思&#xff1f;不知道容器化部署有什么优势&#xff1f;今天我们就来一起看看。 容器化部署是什么意思&#xff1f; 容器化部署是指将软件代码和所需的所有组件&#xff08;例如库、框架和其他依赖项&#xff09;打包在一起&#xff0c;让它…...

2024年赣州旅游投资集团社会招聘笔试真

2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

ardupilot 开发环境eclipse 中import 缺少C++

目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

初探Service服务发现机制

1.Service简介 Service是将运行在一组Pod上的应用程序发布为网络服务的抽象方法。 主要功能&#xff1a;服务发现和负载均衡。 Service类型的包括ClusterIP类型、NodePort类型、LoadBalancer类型、ExternalName类型 2.Endpoints简介 Endpoints是一种Kubernetes资源&#xf…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storms…...

k8s从入门到放弃之HPA控制器

k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率&#xff08;或其他自定义指标&#xff09;来调整这些对象的规模&#xff0c;从而帮助应用程序在负…...

6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙

Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

前端高频面试题2:浏览器/计算机网络

本专栏相关链接 前端高频面试题1&#xff1a;HTML/CSS 前端高频面试题2&#xff1a;浏览器/计算机网络 前端高频面试题3&#xff1a;JavaScript 1.什么是强缓存、协商缓存&#xff1f; 强缓存&#xff1a; 当浏览器请求资源时&#xff0c;首先检查本地缓存是否命中。如果命…...