博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python学习笔记——信号模块signal
阅读量:6001 次
发布时间:2019-06-20

本文共 3785 字,大约阅读时间需要 12 分钟。

基于的学习基础,进一步学习Python标准库中的signal模块。

尽管signal是python中的模块,但是主要针对UNIX平台(比如Linux,MAC OS),而Windows内核中由于对信号机制的支持不充分,所以在Windows上的Python不能发挥信号系统的功能。

signal模块负责python程序内部的信号处理;典型的操作包括信号处理函数、暂停并等待信号,以及定时发出SIGALRM等;

1 signal基本信号名

引入模块: import signal 

signal.SIGHUP   # 连接挂断;signal.SIGILL   # 非法指令;signal.SIGINT   # 终止进程(ctrl+c);signal.SIGTSTP  # 暂停进程(ctrl+z);signal.SIGKILL  # 杀死进程(此信号不能被捕获或忽略);signal.SIGQUIT  # 终端退出;signal.SIGTERM  # 终止信号,软件终止信号;signal.SIGALRM  # 闹钟信号,由signal.alarm()发起;signal.SIGCONT  # 继续执行暂停进程;

2 常用信号处理函数

2.1 设置发送SIGALRM信号的定时器

 signal.alarm(time) 

参数:time为时间参数

功能:在time时间后,向进程自身发送SIGALRM信号

import signalimport timesignal.alarm(4)#4s后终止程序while True:    time.sleep(1)    print("学习python中...")

运行

学习python中...学习python中...学习python中...闹钟

 

当在一个程序中出现两个signal.alarm()函数时

import signalimport timeprint(signal.alarm(3)) # 0time.sleep(1)print(signal.alarm(4)) # 2while True:    time.sleep(1)    print("学习python中...")

运行

02学习python中...学习python中...学习python中...闹钟

注意:在一个进程中,只能设置一个时钟,如果设置第二个则会覆盖第一个的时间,返回地一个的剩余时间,第一个闹钟返回0。

 

使用signal.pasue阻塞函数:

signal.pause() Wait until a signal arrives。让进程进程暂停,以等待信号(什么信号均可);也即阻塞进程进行,接收到信号后使进程停止

import signalimport timeprint(signal.alarm(3)) # 0time.sleep(1)print(signal.alarm(4)) # 3#阻塞等待信号的发生,如论什么信号都可以signal.pause()while True:    time.sleep(1)    print("学习python中...")

运行

02闹钟

 

2.2 设置信号处理函数

 signal.signal(sig, handler) 

功能:按照handler制定的信号处理方案处理函数

参数

sig:拟需处理的信号,处理信号只针对这一种信号起作用sig

hander:信号处理方案

    在信号基础里提到,进程可以无视信号、可采取默认操作、还可自定义操作;当handler为下列函数时,将有如下操作:

    SIG_IGN:信号被无视(ignore)或忽略

    SIG_DFL:进程采用默认(default)行为处理

   function:handler为一个函数名时,进程采用自定义函数处理

   *SIGSTOP SIGKILL不能处理,只能采用

 

示例1

import signal#6s后终止程序signal.alarm(6)#遇到SIGINT ctrl+c时,忽略SIG_IGNsignal.signal(signal.SIGINT,signal.SIG_IGN)signal.pause()

运行后6s 打印出: 闹钟 

如果在运行中在键盘中输入CTRL+C也无济于事,此时输出结果 ^C^C^C^C^C^C^C^C闹钟 

原因分析

(1)signal.signal(signal.SIGINT, signal.SIG_IGN) 表示遇到信号SIGINT  CTRL + C,时,忽略SIG_IGN该信号。

所以在程序运行中从键盘输入ctrl+c(在终端上显示 ^C )时无效。

(2)当signal.alarm(6)计时6秒后,直接在终端上输出 “闹钟” 后退出。

(3)signal.pause()是为了阻塞进程,等待信号。如果没有这句话,可以在程序中更变为

while True:    pass

效果一样,如果没有这段代码,则没有直接运行结束,终端上没有任何输出显示。注意:这里的signal.alarm()是在程序运行中,6秒后停止进程。

 

示例2 

进程中默认信号方式处理

import signal#6s后终止程序signal.alarm(6)signal.signal(signal.SIGALRM,signal.SIG_DFL)signal.pause()

运行后终端显示  闹钟

 

示例3

有些原操作系统规定了的进程收到信号后的默认行为,使用signal.signal()可以通过绑定信号处理函数来修改进程收到信号后的行为,实现个性化处理。

也即改变原默认行为,但是SIGTOP和SIGKILL两个信号的默认行为是不可更变的。

from signal import *import timedef handler(signum,frame):    if signum == SIGALRM:        print('时间到了')    elif signum == SIGINT:        print("CTRL + C 无效")alarm(5)signal(SIGINT,handler)signal(SIGALRM,handler)while True:    print('Waiting....')    time.sleep(2)

运行结果

Waiting....Waiting....Waiting....时间到了Waiting....^CCTRL + C 无效Waiting....^CCTRL + C 无效Waiting....^\退出 (核心已转储)

说明:

(1)signal.signal() 通过绑定函数更变了信号的处理方式

(2)如果没有改变alarm()信号的处理方式,signal.alarm()在运行5s后会将终止程序并输出“闹钟”字样

(3)从设备终端键盘输入ctrl+c无效后,此时可以输入ctrl+\退出程序

(4)def handler(signum,frame)中frame,第一个参数是用来识别信号(signum),第二个信号是用来获得信号发生时,进程栈的状况(stack frame对象),这两个参数都是由signal.signal()函数传递的。 参考

 

示例4

import signal# Define signal handler functiondef myHandler(signum, frame):    print('I received: ', signum)# register signal.SIGTSTP's handlersignal.signal(signal.SIGTSTP, myHandler)signal.pause()print('End of Signal Demo')

运行(运行后设备终端键盘输入ctrl+z)

^ZI received:  20End of Signal Demo

说明:

(1)signal.signal()函数来预设信号处理函数;

(2)当程序执行signal.pause()来让进程暂停(被阻塞)以等待信号,此时,按下ctrl + z 向该进程发送SIGTSTP信号,当信号signal.SIGTSTP信号传递给该进程后,进程从被阻塞中恢复,并根据预设,执行SIGTSTP的信号处理函数myHandler()。

(3)myHandler()的两个参数一个用来识别信号(signum),另一个用来获得信号发生时,进程栈的状况(stack frame);这两个参数都是有signal.signal()函数传递的。

(4)进程并不一定要使用signal.pause()暂停以等待信号,它也可以在进行工作中接受信号,比如将上面的signal.pause()改为一个需要长时间工作的循环或死循环。

 

总结:常用信号处理函数:

 

3 常用信号处理函数

 signal.signal(signalnum, handler)  设置信号处理的函数

 signal.alarm(time) 设置发送SIGALRM信号的定时器

 os.kill 这个不属于signal模块,但其可以使用给某一进程发送信号

 

参考:

和 (一样)

 

转载地址:http://ubdmx.baihongyu.com/

你可能感兴趣的文章
标准功能模块组件 -- 名片管理组件,C\S 版本的标准用例程序,可以参考权限实现方法...
查看>>
zygote进程图
查看>>
ldap快速配置
查看>>
docker之docker-machine用法
查看>>
IIS 7启用static JSON文件能POST方法
查看>>
P5205 【模板】多项式开根
查看>>
微博mini for Windows Phone 8 开发那些事
查看>>
redis文章索引
查看>>
OpenSSH利用处理畸形长度密码造成的时间差,枚举系统用户(CVE-2016-6210)
查看>>
Javascript回调函数
查看>>
可能是最简单的面向对象入门教程(二)为什么要有类型
查看>>
配置Openfiler做ISCS实验
查看>>
Maven启用代理访问
查看>>
LDAP & Implementation
查看>>
hdu 4597 Play Game
查看>>
hdu 1398 Square Coins (母函数)
查看>>
twitter storm 源码走读之5 -- worker进程内部消息传递处理和数据结构分析
查看>>
CCF 201503-4 网络延时
查看>>
.net获取select控件中的文本内容
查看>>
Windows 8 Metro App开发[5]导航栏(AppBar)的使用
查看>>