前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >内核的“信号处理”——发送与响应

内核的“信号处理”——发送与响应

作者头像
glinuxer
发布于 2019-04-10 03:20:45
发布于 2019-04-10 03:20:45
1.9K0
举报
文章被收录于专栏:专注网络研发专注网络研发

信号处理是写任何服务程序都逃避不了的问题。比如写TCP服务程序,一般都要将SIGPIPE设置为SIG_IGN。—— 当TCP连接由内核判定为已“中断”或者说“断连”,而应用层还在尝试往这个连接对应的套接字写入数据时,就会产生SIGPIPE信号。如果应用程序没有注册过SIGPIPE信号处理函数,内核则会执行SIGPIPE的默认处理即终止当前进程。但是对于TCP服务来说,出现这种情况是属于正常范围内(譬如对端直接RST了连接),所以服务程序应该直接设置忽略SIGPIPE。

对于应用层程序来说,信号就像一个“中断”。外部硬件通过可以注册中断处理函数,应用层也可以注册信号处理函数。一般来说,硬件中断乃至中断处理函数,可以打断CPU当前的处理流程,而信号同样也可以打断应用层的当前处理流程。两者极其相似。

硬件中断是硬件产生一个信号,经中断控制器APIC,发送到对应CPU的INTR或NMI引脚,通知CPU有个中断发生了。CPU检测到中断信号后,就会中断当前的工作,保存上下文,转而根据中断号调用相应的中断处理函数。那么,信号是如何触发和响应的呢?

信号的触发,比较简单。任何有权限的用户或者进程都可以给另外一个进程发送信号,如使用kill命令。其内核实现也很简单。以kill系统调用为例,其调用顺序如下:kill->kill_something_info->kill_pid_info->do_send_sig_info->send_signal->__send_signal->sigaddset

即将发送信号添加到进程或者进程组的struct sigpending中。

然后调用complete_signal,其内部会调用signal_wake_up唤醒目的进程。至此,完成了信号的发送。

那么,目的进程是如何“响应”信号呢?从发送的过程看到,信号只是简单加到当前线程task_struct的结构中(struct sigpending属于task_struct)。所以,目的进程的信号响应,一定是由内核检查并完成的。

既要满足信号可以打断应用程序执行流程,又要保证性能,只有在目的进程陷入内核态,并返回用户态之前,完成信号响应和处理,是最为合适的。

而目的进程什么情况下会陷入内核态呢?最直接的答案就是系统调用。

同时为了研究signal的处理,我在内核信号处理的入口函数do_signal增加了一句dump_stack(),来打印调用栈。这个程序启动以后,就调用sleep陷入内核态并进入sleep状态,然后kill掉这个进程。这时,dmesg的输出如下:

从上面的输出可以明显看到,do_signal是在系统调用返回用户态前被调用。当进程通过系统调用陷入内核态时,一般情况下都会被信号中断调用,从而返回用户态。也正是返回应用态之前,内核调用了do_signal。

那么如果这个程序没有任何系统调用,会怎么样呢?还可以被另外一个进程kill杀掉吗?将程序改写为:

然后运行该程序

可以看到test_signal一直占用100%的CPU,也就是该进程始终处于RUNNING状态。然后在另外一个终端下,执行killall test_signal。

测试程序test_signal仍然被信号中断,从而退出。而dmesg的输出下:

从栈顶“retint_user”可以看出,这次do_signal是在中断返回时被调用的。也就是说,test_signal因为“中断”而陷入了内核态,并在处理完中断返回应用态之前,调用了do_signal。—— 至于为什么从“retint_user”就可以确定是处理“中断”,大家自行搜索相关资料吧。或者留到以后有机会再分享这块知识。

“信号”的响应总结为一句话:应用态进程由于系统调用、中断或异常,而陷入内核态后,在返回应用态之前,内核会进行信号的检查和处理。

PS:

  1. 本文中的示例程序没有考虑代码的健壮性。如printf和exit实际上是非信号安全函数,不能在信号中断处理函数中调用。
  2. 本文未涉及信号处理函数的调用机制,留待以后分解。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-06-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LinuxerPub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文