平常我们启动一个后台进程,会通过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,子进程也自动退出的问题记录相关推荐

  1. php修改父进程变量,shell子进程修改父进程的环境变量值

    shell子进程修改父进程的环境变量值 脚本中的环境变量通过 export 导出,脚本中调用其他脚本使用这个变量 这里有两个脚本程序 hello 和 hello1 hello 脚本代码 #!/bin/ ...

  2. 父进程产生一系列子进程,每个子进程打印自己的PID然后退出,父进程最后打印PID

    #include<stdio.h> #include<stdlib.h> #include <unistd.h> //父进程产生一系列子进程,每个子进程打印自己的P ...

  3. linux之父进程使用kill函数杀死子进程

    父进程循环创建5个子进程,并且父进程杀死第三个创建的子进程. 代码:kill.c #include <stdlib.h> #include <stdio.h> #include ...

  4. linux父进程中显示子进程pid,请教linux下c语言函数fork父进程打印子进程的PID

    请教linux下c语言函数fork父进程打印子进程的PID 关注:296  答案:2  信息版本:手机版 解决时间 2019-01-14 04:55 雨不眠的下 2019-01-13 12:23 用于 ...

  5. linux子进程父进程例子,linux 子进程访问父进程

    问题分析 ECS Linux 系统下 Apache 的默认工作模式是 prefork MPM,使用多个子进程,每个子进程只有一个线程.每个进程在某个确定的时间只能维持一个连接,效率高,但内存占用量比较 ...

  6. .net父进程被终止时,自动终止子进程

    做过selenium爬虫的人,一定有一个烦恼,那就是selenium会启动很多子进程,爬虫终止的时候,由于各种原因,总会有些僵尸进程(chrome,chromedriver)残留在内存,不清除这些僵尸 ...

  7. 父进程与子进程间相互发送信号

    最近想要实现父子进程间的通信,两个进程间能"软中断",也就是使用signal函数将进程与handler函数绑定. 其中的难点在于如何在父进程中获取子进程的pid,由于实际的程序中, ...

  8. 子进程及时知道父进程已经退出的最简单方案

    [精彩] 子进程及时知道父进程已经退出的最简单方案? http://www.chinaunix.net 作者:yuonunix  发表于:2003-10-31 10:14:14 [发表评论] [查看原 ...

  9. Linux中父进程为何要苦苦地知道子进程的死亡原因?

    白发人送黑发人 一个普遍的常识是,在Linux里面总是"白发人送黑发人",子进程死亡,父进程透过wait()等待子进程死亡,并清理子进程僵尸,当然父进程也可以因此而获得子进程的死亡 ...

最新文章

  1. 超越MobileNetV3!Facebook提出更轻更快的FBNetV2
  2. mysql text 最大长度 报错 Row size too large. The maximum row size for the used table type
  3. wxWidgets:wxProcessEvent类用法
  4. QT的QModbusResponse类的使用
  5. 单片机定时器精准定时_PIC单片机的定时器精准计时的计算
  6. 从mysql到大数据(二)--数据库的认识
  7. EIM正在迎来自己的春天
  8. 工程师已经被虐到不行不行的了
  9. 新增标签 html知识,互联网常识:html5有哪些新增标签
  10. 让VMware ESXi 5.5与Windows时间服务器同步
  11. 使用GDAL打开裸数据(RAW)
  12. 【CS229】代价函数与梯度下降
  13. 【bzoj1712】[Usaco2007 China]Summing Sums 加密 矩阵乘法
  14. 【初学大数据】CentOS7安装hadoop3.3.2完全分布式详细流程
  15. 织梦php模板安装教程,dedecms织梦网整站模板通用安装教程(图文)
  16. 51单片机延时函数不起作用
  17. 用python把数据画成饼状图_Python学习第92课——数据可视化之饼状图绘制
  18. 【21SR】Designing a Practical Degradation Model for Deep BlindImage Super-Resolution
  19. prescan8.5 百度网盘下载链接及安装过程
  20. eclipse c语言 自动补全,eclipse里头怎么设C/C++的智能提示

热门文章

  1. java写excel
  2. RDP、VNC、SPICE协议性能分析之网络带宽
  3. 区域治理杂志区域治理杂志社区域治理编辑部2022年第40期目录
  4. python整数除法保留两位小数
  5. Android 自定义View二(深入了解自定义属性attrs.xml)
  6. 【转】Swagger详解(SpringBoot+Swagger集成)
  7. -Dmaven.multiModuleProjectDirectory system propery is not set. Check $M2_HOME environment variable a
  8. 2021龙岩一中高考成绩查询,喜报!龙岩这7所一中的高考成绩出炉啦~
  9. 产后修复治疗仪方案/案列/APP/网站
  10. WORD之smartart