一、信号用来干什么?
在linux系统中,我们的各个程序是通过进程进行管理的,在一般情况下,每个进程各司其职,各谋其政,这样能够保证各个部门解耦合,有条不絮的进行工作。但是在某些情况下,比如说财务部门某人卷款跑路了,导致公司流动资金为负,那么这个时候生产技术部门就必须及时调整购买计划和生产政策,保证公司不至于在产能不够的情况下进行大量生产,把自己活活拖死。那么通知给这个生产技术部的就是这个叫“信号”的小家伙。
信号就是用来进行进程间通信的
二、信号的产生,触发
- 信号产生 :
信号可以由内核产生(硬件错误),也能由进程直接产生,一般情况下,信号是受内核控制的。内核中有某个进程要发送信号给另一个进程时,一般会先把这个信号放在内核的表里面,当内核的系统调用完成时,会去看看这个表,如果有相关进程的信号,就执行相关操作。
- 信号有两种触发方式:
被动式:,内部检测到了系统事件,比如说我在执行某个程序的时候按下了ctrl+c,这个时候就会发出中断信号,中断当前终端上的进程,这种属于被动的,没有事先设置好的,像stm32中所说的外部中断。
主动式:主动式是指系统调用相应的命令进行传递信号。比如定时器中断,只要到了指定的时间,就进行中断,处理相应其他函数。
- 信号处理会出现以下几种情况:
1、进行系统调用时,触发了信号
系统调用具有最高的优先级,只有在系统调用结束后,我们的内核才会去看有没有信号触发,不过也有例外,有几个系统调用是可以被被打断的,比如说:wait(),pause()以及慢速设备(打印机,终端等)的read(),write(),open()等。如果系统调用被打断,返回的是-1
2、进行信号处理时,触发了另一个信号
当信号处理的过程中,又出现了另一个信号,这个时候不会进行中断,系统会把这个信号存储起来,直到信号处理函数被执行完毕后才会重新调用另一个信号的处理函数
- 对待信号的态度:
1、无视(ignore):不管有没有信号,都不理睬
2、默认:使用信号的默认操作,比如SIGCONT是停止,SIGINT是暂停
3、自定义:自己定义收到信号的操作,比如闹钟响了,我要起床,就是自定义操作
三、基本的信号
SIGINT 在按下中断键CTRL+C时触发,内核会中断(INTERRUPT)该终端上相关的所有进程
SIGQUIT 在按下CTRL+\键时触发,内核会让终端上的运行的进程退出
SIGTSTP 在按下CTRL+Z键时触发,内核会让终端上的运行的进程暂停
SIGCONT 通知进程继续
SIGALRM 定时器,在设定一定时间后触发
四、信号在python的应用
python有个signal的包,使用如下:
singnal.signal(signalnum, handler)
这个函数可以用来对预设信号处理的函数
当handler为signal.SIG_IGN,表示信号被无视
当handler为signal.SIG_DEF,表示使用信号的默认操作
当handler为一个自定义函数时,表示信号触发执行自定义函数
import signal
# Define signal handler function
def Handler(signum, frame):
print('I received: ', signum)
# register signal.SIGTSTP's handler
signal.signal(signal.SIGTSTP, Handler)
signal.pause()
print('End of Signal Demo')
上面表示在执行了暂停操作,在等待信号触发,当按下ctrl+z触发停止暂停的信号,。