1. 前言

    最近在做一个linux嵌入式产品的时候发现,reboot命令不起作用,经过定位确定是自己的守护进程的问题,reboot命令在给守护进程发SIGTERM信号时未能关闭进程。于是查找守护进程代码发现了如下代码:
    c signal( SIGTERM, SIG_IGN );// 忽略SIGTERM信号
    所以把这句代码注释掉后,程序恢复正常。这里就涉及到一个reboot命令的流程,以及linux的信号处理机制的问题。接下来做一个分析。

  2. reboot的处理流程
    在这里插入图片描述
    普通的reboot是通过busybox为入口,进入halt_main函数,然后给init进程发送SIGTERM信号,init进程接收到信号后给其他进程发送终止信号,最后调用C库函数reboot,reboot通过系统调用sys_reboot进入内核,内核将整个系统重启。其中在shell中执行reboot –f则通过halt_main直接调用C函数reboot,不经过init进程。

可见reboot是通过SIGTERM信号来结束进程的,SIMGTERM信号的描述是这样的:
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

3.lilinux 信号列表及分析
SIGTERM
程序结束(terminate)信号, 与SIGKILL不同的是该信号可以被阻塞和处理。通常用来要求程序自己正常退出,shell命令kill缺省产生这个信号。如果进程终止不了,我们才会尝试SIGKILL。

SIGHUP
本信号在用户终端连接(正常或非正常)结束时发出, 通常是在终端的控制进程结束时, 通知同一session内的各个作业, 这时它们与控制终端不再关联。
登录Linux时,系统会分配给登录用户一个终端(Session)。在这个终端运行的所有程序,包括前台进程组和 后台进程组,一般都属于这个 Session。当用户退出Linux登录时,前台进程组和后台有对终端输出的进程将会收到SIGHUP信号。这个信号的默认操作为终止进程,因此前台进 程组和后台有终端输出的进程就会中止。不过可以捕获这个信号,比如wget能捕获SIGHUP信号,并忽略它,这样就算退出了Linux登录,wget也 能继续下载。
此外,对于与终端脱离关系的守护进程,这个信号用于通知它重新读取配置文件。
其它信号的定义可以参考以下文章
linux 信号列表及分析

测试进程对信号的处理可以使用kill命令

root@dev:~# ps -aux|grep watchdog
root      2387  0.6  0.1   4884   784 ?        S    17:16   0:06 /home/et1000/watchdog
root      8959  0.0  0.0   2072   540 ttyS0    S+   17:34   0:00 grep watchdog
root@dev:~# kill -TERM 2387
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐