-
-
[原创]LINUX0.11信号机制
-
发表于:
2019-1-16 14:54
6018
-
信号(signal)是Linux操作系统在软件层面上对中断的模拟,是一种异步通信机制。进程之间可以相互发送信号来通知对方发生了什么事情,一个进程不必等待一个信号的到来,他也不知道什么时候会有信号到来。
进程对信号有三种处理方法:
第一种是类似中断的处理程序,对于需要处理的信号,进程可以指定处理函数,由该函数来处理。进程通过系统调用signal来指定进程对某个信号的处理行为。
第二种方法是,忽略某个信号,对该信号不做任何处理,就象未发生过一样。
第三种方法是,对该信号的处理保留系统的默认值,这种缺省操作,对大部分的信号的缺省操作是使得进程终止。
信号产生
信号在进程中注册
信号执行和注销
信号产生有两个来源:硬件来源(按下键盘ctrl+c或者硬件故障)和软件来源(向其他进程发信号比如kill、alarm),linux0.11中定义了22种信号。
include/sys/signal.h
注册信号就是在与信号绑定的任务上指定对某信号的处理句柄。任务控制结构中有三个字段signal、sigaction[32]、blocked用于描述本任务对信号的处理方式。
signal是信号处理位图,任务收到一个信号signal中相应的位就会置1。sigaction指定了对某一信号的处理句柄和处理方式,这一点类似于中断向量。如果blocked中某一位被置1则表示对应的信号被阻塞处于阻塞状态,只有blocked中的该位置0才能处理该信号。所以信号的处理与中断的处理是很类似的。
再来看一下sigaction结构。在任务控制结构中有一个sigaction[32]的数组结构,该数组就是本任务的信号处理向量表,下标对应于信号的数值减一(信号值都是从1开始)。
include/sys/signal.h
sa_handler指定了信号处理句柄,指向用户进程中某一代码块。
sa_flags指定了对信号句柄的处理方式,一共有三种:SA_NOCLDSTOP表示进程处于停止状态,不对信号做处理。SA_NOMASK表示当前信号在处理的过程中可以收相同的信号,这个时候可以运行信号嵌套。SA_ONESHOT指明信号处理函数一旦被调用过就恢复到默认的信号处理函数去,即使得sa_handler=SIG_DFL。
sa_mask是当前信号在处理的过程中需要屏蔽掉哪些信号,通常用于防止信号处理的嵌套。
sa_restorer是用于信号处理完毕后清理用户堆栈并返回到正常程序流的句柄,由gcc编译时的函数库提供。
include/sys/signal.h
综上所述,对信号的注册其实就是设置task_struct中的sigaction[32]数组用于指定对信号的处理方式。
系统调用sys_signal和sys_sigaction都用于完成信号的注册,区别是sys_signal按照系统默认的方式完成信号注册,而sys_sigaction可以由用户自己定义sigaction结构并赋值给task_struct。
kernel/signal.c
sys_signal接收三个参数,信号值、处理句柄、堆栈恢复句柄,按照默认的处理方式处理信号,即允许信号嵌套、只能使用1次,用完即清空句柄,最后返回旧的处理句柄。
sys_sigaction也是接收三个参数,信号值、用户进程提供的sigaction指针和旧的sigaction保存位置。如果指定了oldaction则将旧的sigaction保存其中。这种定义方式较sys_signal灵活。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课