python中对信号的处理详解
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
python中对信号的处理详解
⽬录
什么是信号
Python的信号处理
Python对信号的处理
信号枚举
信号函数
signal.alarm(time)
signal.pause()
signal.setitimer(which, seconds, interval)
os.getpid()
Windows下信号的使⽤
当signal handling需要参数怎么办
忽略信号
常⽤的信号
总结
什么是信号
信号(signal)-- 进程间通讯的⼀种⽅式,也可作为⼀种软件中断的⽅法。
⼀个进程⼀旦接收到信号就会打断原来的程序执⾏来按照信号进⾏处理。
简化术语,信号是⼀个事件,⽤于中断运⾏功能的执⾏。
信号始终在主Python线程中执⾏。
对于信号,这⾥不做详细介绍。
Python封装了操作系统的信号功能的库 singal 的库。
singal 库可以使我们在python程序中中实现信号机制。
Python的信号处理
⾸先需要了解Python为什么要提供 signal Library。
信号库使我们能够使⽤信号处理程序,以便当接收信号时都可以执⾏⾃定义任务。
Mission:当接收到信号时执⾏信号处理⽅法
可以通过使⽤ signal.singal() 函数来实现此功能
Python对信号的处理
通常情况下Python 信号处理程序总是会在主 Python 主解析器的主线程中执⾏,即使信号是在另⼀个线程中接收的。
这意味着信号不能被⽤作线程间通信的⼿段。
你可以改⽤ threading 模块中的同步原语。
Python信号处理流程,需要对信号处理程序(signal handling )简要说明。
signal handling 是⼀个任务或程序,当检测到特定信号时,处理函数需要两个参数,即信号id signal number (Linux 中 1-64),与堆栈帧 frame。
通过相应信号启动对应signal handling ,signal.signal() 将为信号分配处理函数。
如:当运⾏⼀个脚本时,取消,此时是捕获到⼀个信号,可以通过捕获信号⽅式对程序进⾏异步的优雅处理。
通过将信号处理程序注册到应⽤程序中:
import signal
import time
def handler(a, b): # 定义⼀个signal handling
print("Signal Number:", a, " Frame: ", b)
signal.signal(signal.SIGINT, handler) # 将handle分配给对应信号
while True:
print("Press ctrl + c")
time.sleep(10)
如果不对对应信号进⾏捕获处理时,python将会抛出异常。
root@Seal:/mnt/d/pywork/signal# python signal.py
^CTraceback (most recent call last):
File "signal.py", line 3, in <module>
while True:
KeyboardInterrupt
信号枚举
信号的表现为⼀个int,Python的信号库有对应的信号枚举成员
其中常⽤的⼀般有,
SIGINT control+c
SIGTERM 终⽌进程软件终⽌信号
SIGKILL 终⽌进程杀死进程
SIGALRM 超时
信号说明SIG_DFL
SIG_IGN标准信号处理程序,它将简单地忽略给定的信号
SIGABRT SIGIOT 来⾃ abort 的中⽌信号。
abort 导致异常进程终⽌。
通常由检测内部错误或严重破坏约束的库函数调⽤。
例如,如果堆的内部结构被堆溢出损坏, malloc() 将调⽤ abort()
SIGALRM SIGVTALRM SIGPROF 如果你⽤ setitimer 这⼀类的报警设置函数设置了⼀个时限,到达时限时进程会接收到 SIGALRM, SIGVTALRM 或者 SIGPROF。
但是这三个信号量的含义各有不同,SIGALRM 计时的是真实时
间,SIGVTALRM计时的是进程使⽤了多少CPU时间,⽽ SIGPROF 计时的是进程和代表该进程的内核⽤了多少时间。
SIGBUS总线发⽣错误时,进程接收到⼀个SIGBUS信号。
举例来说,存储器访问对齐或者或不存在对应的物理地址都会产⽣SIGBUS信号。
SIGCHLD当⼦进程终⽌、被中断或被中断后恢复时,SIGCHLD信号被发送到进程。
该信号的⼀个常见⽤法是指⽰操作系统在⼦进程终⽌后清理其使⽤的资源,⽽不显式调⽤等待系统调⽤。
SIGILL⾮法指令。
当进程试图执⾏⾮法、格式错误、未知或特权指令时,SIGILL信号被发送到该进程。
SIGKILL发送SIGKILL信号到⼀个进程可以使其⽴即终⽌(KILL)。
与SIGTERM和SIGINT相不同的是,这个信号不能被捕获或忽略,接收过程在接收到这个信号时不能执⾏任何清理。
以下例外情况适⽤:
SIGINT来⾃键盘的中断 (CTRL + C)。
KeyboardInterrupt
SIGPIPE当⼀个进程试图写⼊⼀个没有连接到另⼀端进程的管道时,SIGPIPE信号会被发送到该进程。
**SIGTERM **终结信号。
KILL -15 |KILL
SIGUSR1
SIGUSR2⽤户⾃定义信号
SIGWINCH终端窗⼝⼤⼩已变化
SIGHUP在控制终端上检测到挂起或控制进程的终⽌。
Reference:[signal-wikipedia](
信号函数
Python的信号库中也有很多常⽤的函数
signal.alarm(time)
创建⼀个 SIGALRM 类型的信号,time为预定的时间,设置为0时取消先前设置的定时器
signal.pause()
可以使代码逻辑处理过程睡眠,直到收到信号,然后调⽤对应的handler。
import os
import time
def do_exit(sig, stack):
raise SystemExit('Exiting')
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGUSR1, do_exit)
print('My PID:', os.getpid())
signal.pause()
在执⾏时,忽略了ctrl + c的信号,对USR1做退出操作
signal.setitimer(which, seconds, interval)
which: signal.ITIMER_REAL,signal.ITIMER_VIRTUAL 或 signal.ITIMER_PROF
seconds:多少秒后触发which。
seconds设置为0可以清除which的计时器。
interval:每隔interval秒后触发⼀次
os.getpid()
获得当前执⾏程序的pid
Windows下信号的使⽤
在Linux中,可以通过任何可接受的信号枚举值作为信号函数的参数。
在Windows中,SIGABRT, SIGFPE, SIGINT, SIGILL, SIGSEGV, SIGTERM, SIGBREAK。
当signal handling需要参数怎么办
在⼀些时候,signal handling的操作需要对应主进程传递进来⼀些函数,⽽在整个项⽬中执⾏过程中的变量与 signal handling 不处于⼀个作⽤域中,⽽signal.signal() 不能传递其他的参数,这个时候可以使⽤ partial 创建⼀个闭包来解决这个问题。
例如:
import signal
import os
import sys
import time
from functools import partial
"""
这⾥signal frame默认参数需要放到最后
"""
def signal_handler(test_parameter1, test_parameter2, signal_num, frame):
print "signal {} exit. {} {}".format(signal_num, test_parameter1, test_parameter2)
sys.exit(1)
a=1
b=2
signal.signal(signal.SIGINT, partial(signal_handler, a, b) )
print('My PID:', os.getpid())
signal.pause()
忽略信号
signal定义了忽略接收信号的⽅法。
为了实现信号的处理,需要使⽤signal.signal() 将默认的信号与signal.SIG_IGN 注册,即可忽略对应的信号中断,kill -9 不可忽略。
import signal
import os
def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
raise SystemExit('Exiting')
return
if __name__ == '__main__':
# register the signal to be caught
signal.signal(signal.SIGUSR1, receiveSignal)
# register the signal to be ignored
signal.signal(signal.SIGINT, signal.SIG_IGN)
# output current process id
print('My PID is:', os.getpid())
signal.pause()
常⽤的信号
import signal
import os
import time
import sys
def readConfiguration(signalNumber, frame):
print ('(SIGHUP) reading configuration')
return
def terminateProcess(signalNumber, frame):
print ('(SIGTERM) terminating the process')
sys.exit()
def receiveSignal(signalNumber, frame):
print('Received:', signalNumber)
return
signal.signal(signal.SIGHUP, readConfiguration)
signal.signal(signal.SIGINT, receiveSignal)
signal.signal(signal.SIGQUIT, receiveSignal)
signal.signal(signal.SIGILL, receiveSignal)
signal.signal(signal.SIGTRAP, receiveSignal)
signal.signal(signal.SIGABRT, receiveSignal)
signal.signal(signal.SIGBUS, receiveSignal)
signal.signal(signal.SIGFPE, receiveSignal)
#signal.signal(signal.SIGKILL, receiveSignal)
signal.signal(signal.SIGUSR1, receiveSignal)
signal.signal(signal.SIGSEGV, receiveSignal)
signal.signal(signal.SIGUSR2, receiveSignal)
signal.signal(signal.SIGPIPE, receiveSignal)
signal.signal(signal.SIGALRM, receiveSignal)
signal.signal(signal.SIGTERM, terminateProcess)
总结
到此这篇关于python中对信号处理的⽂章就介绍到这了,更多相关python信号处理内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。