关闭终端后,后台作业退出的分析

2024-05-07 11:08

本文主要是介绍关闭终端后,后台作业退出的分析,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

先把结论写在上面:

-- 内核驱动发现终端(或伪终端)关闭,给对应终端的控制进程(bash)发 SIGHUP 
-- bash收到SIGHUP后,会给各个作业(包括前后台)发送SIGHUP,然后自己退出
-- 前后台的各个任务,收到来自 bash 的SIGHUP,退出(如果程序会处理SIGHUP,就不会退出)

PS: 这里所谓终端关闭就是指内核感知不到终端了,远程登录时的网络断开、sshd挂掉之类的情况也算在内。

PPS: SIGHUP会在以下情况发出

1、终端关闭时,该信号被内核发送到session首进程

2、session首进程退出时,该信号被内核发送到该session中的前台进程组中的每一个进程

3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。

PPPS: bash 收到SIGHUP后会转发给各个任务(job)





下面是”纠结“的分析过程:


现象:./a.out & 这种方式运行,关闭终端后,a.out也会终止


分析:

首先,写了个简单的脚本看是什么信号导致的后台作业退出。

a.pl:

#! /usr/bin/perl -w


$SIG{HUP} = sub{print "HUP/n"};

$SIG{KILL} = sub{print "KILL/n"};

$SIG{TERM} = sub{print "TERM/n"};


while (1){

    sleep 1;

}


运行a.pl: ./a.pl > log.txt &;关闭终端;在另一个终端查看log.txt,内容为HUP,且a.pl仍然存活

结论:是SIGHUP信号导致后台作业退出


然后,查看SIGHUP从哪里来,google + baidu,搜索到最多的那个(就是来回转载的,中文技术资料的冗余程度,你懂的!)

SIGHUP会在以下3种情况下被发送给相应的进程:

1、终端关闭时,该信号被发送到session首进程以及作为job提交的进程(即用 & 符号提交的进程)

2、session首进程退出时,该信号被发送到该session中的前台进程组中的每一个进程

3、若父进程退出导致进程组成为孤儿进程组,且该进程组中有进程处于停止状态(收到SIGSTOP或SIGTSTP信号),该信号会被发送到该进程组中的每一个进程。


       到这一步,放佛已经很明了,终端或者伪终端关闭后,SIGHUP会发给“作为job提交的进程”。

       然而我恰好犯贱,想多浪费一些时间,又翻看了一下《Unix环境高级编程》,发现其实上面标粉红的那一部分貌似是主观意见而已。但是作为job提交的 a.pl 确实收到了一个SIGHUP,是谁在什么情形下偷偷发出的呢?

       于是上CSND求牛人作答:http://topic.csdn.net/u/20110402/23/0eebdafa-c2c1-4ed5-b981-365f80bb6e7f.html

       鉴于回答热度不高,无奈又上stackoverflow问了一下:http://stackoverflow.com/questions/5527405/where-is-sighup-from-sshd-forks-a-child-to-create-a-new-session-kill-this-chil

       stackoverflow上的回答还算有些靠谱,自己仿佛觉得,mm,这个SIGHUP来自内核的driver。


继续验证 a.pl 收到的确来自内核driver,而不是相干的进程(如父进程bash)

又去查看bash的手册,终于看到

The shell exits by default upon receipt of a SIGHUPBefore exiting, an interactive shell resends the SIGHUP to all jobs, running or stopped. Stopped jobs are sent SIGCONT to ensure that they receive the SIGHUP.

真相接近大白:原来是bash在收到内核driver发出的SIGHUP后,转发给 a.pl 的 !

欣喜之余,跑到csdn自己提问的那个链接匆忙结贴。




待续:

使用trap命令,运行

i=-1;while((++i<33)); do trap "echo $i >> log.txt" $i; done

强行关闭终端,log.txt的内容为

1
18
1
17
0

bash竟然收到这么多信号... 还是我trap用的有问题,为什么bash会收到这些信号呢?

http://topic.csdn.net/u/20110405/09/8f20f0dc-492a-4c3b-bd36-eb8c6f9ff482.html



来源:http://www.flatws.cn/article/program/perl/2011-04-06/19454.html


这篇关于关闭终端后,后台作业退出的分析的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/967175

相关文章

怎么关闭Ubuntu无人值守升级? Ubuntu禁止自动更新的技巧

《怎么关闭Ubuntu无人值守升级?Ubuntu禁止自动更新的技巧》UbuntuLinux系统禁止自动更新的时候,提示“无人值守升级在关机期间,请不要关闭计算机进程”,该怎么解决这个问题?详细请看... 本教程教你如何处理无人值守的升级,即 Ubuntu linux 的自动系统更新。来源:https://

Redis主从/哨兵机制原理分析

《Redis主从/哨兵机制原理分析》本文介绍了Redis的主从复制和哨兵机制,主从复制实现了数据的热备份和负载均衡,而哨兵机制可以监控Redis集群,实现自动故障转移,哨兵机制通过监控、下线、选举和故... 目录一、主从复制1.1 什么是主从复制1.2 主从复制的作用1.3 主从复制原理1.3.1 全量复制

Ubuntu系统怎么安装Warp? 新一代AI 终端神器安装使用方法

《Ubuntu系统怎么安装Warp?新一代AI终端神器安装使用方法》Warp是一款使用Rust开发的现代化AI终端工具,该怎么再Ubuntu系统中安装使用呢?下面我们就来看看详细教程... Warp Terminal 是一款使用 Rust 开发的现代化「AI 终端」工具。最初它只支持 MACOS,但在 20

Redis主从复制的原理分析

《Redis主从复制的原理分析》Redis主从复制通过将数据镜像到多个从节点,实现高可用性和扩展性,主从复制包括初次全量同步和增量同步两个阶段,为优化复制性能,可以采用AOF持久化、调整复制超时时间、... 目录Redis主从复制的原理主从复制概述配置主从复制数据同步过程复制一致性与延迟故障转移机制监控与维

Python使用Colorama库美化终端输出的操作示例

《Python使用Colorama库美化终端输出的操作示例》在开发命令行工具或调试程序时,我们可能会希望通过颜色来区分重要信息,比如警告、错误、提示等,而Colorama是一个简单易用的Python库... 目录python Colorama 库详解:终端输出美化的神器1. Colorama 是什么?2.

Redis连接失败:客户端IP不在白名单中的问题分析与解决方案

《Redis连接失败:客户端IP不在白名单中的问题分析与解决方案》在现代分布式系统中,Redis作为一种高性能的内存数据库,被广泛应用于缓存、消息队列、会话存储等场景,然而,在实际使用过程中,我们可能... 目录一、问题背景二、错误分析1. 错误信息解读2. 根本原因三、解决方案1. 将客户端IP添加到Re

Python中构建终端应用界面利器Blessed模块的使用

《Python中构建终端应用界面利器Blessed模块的使用》Blessed库作为一个轻量级且功能强大的解决方案,开始在开发者中赢得口碑,今天,我们就一起来探索一下它是如何让终端UI开发变得轻松而高... 目录一、安装与配置:简单、快速、无障碍二、基本功能:从彩色文本到动态交互1. 显示基本内容2. 创建链

Redis主从复制实现原理分析

《Redis主从复制实现原理分析》Redis主从复制通过Sync和CommandPropagate阶段实现数据同步,2.8版本后引入Psync指令,根据复制偏移量进行全量或部分同步,优化了数据传输效率... 目录Redis主DodMIK从复制实现原理实现原理Psync: 2.8版本后总结Redis主从复制实

锐捷和腾达哪个好? 两个品牌路由器对比分析

《锐捷和腾达哪个好?两个品牌路由器对比分析》在选择路由器时,Tenda和锐捷都是备受关注的品牌,各自有独特的产品特点和市场定位,选择哪个品牌的路由器更合适,实际上取决于你的具体需求和使用场景,我们从... 在选购路由器时,锐捷和腾达都是市场上备受关注的品牌,但它们的定位和特点却有所不同。锐捷更偏向企业级和专

Springboot使用RabbitMQ实现关闭超时订单(示例详解)

《Springboot使用RabbitMQ实现关闭超时订单(示例详解)》介绍了如何在SpringBoot项目中使用RabbitMQ实现订单的延时处理和超时关闭,通过配置RabbitMQ的交换机、队列和... 目录1.maven中引入rabbitmq的依赖:2.application.yml中进行rabbit