Python使用signal模块实现定时执行
在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点在程序中可以用定时器实现这种功能,于是就开始摸索了,发现需要一些信号的知识...
查看你的linux支持哪些信号:kill -l 即可
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
root@server:~ # kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX root@server:~ # |
信号:进程之间通讯的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。操作系统规定了进程收到信号以后的默认行为,但是,我们可以通过绑定信号处理函数来修改进程收到信号以后的行为,有两个信号是不可更改的SIGTOP和SIGKILL。
发送信号一般有两种原因:
1(被动式) 内核检测到一个系统事件.例如子进程退出会像父进程发送SIGCHLD信号.键盘按下control+c会发送SIGINT信号
2(主动式) 通过系统调用kill来向指定进程发送信号
在C语言中有个setitimer函数,函数setitimer可以提供三种定时器,它们相互独立,任意一个定时完成都将发送定时信号到进程,并且自动重新计时。参数which确定了定时器的类型:
ITIMER_REAL 定时真实时间,与alarm类型相同。 SIGALRM
ITIMER_VIRT 定时进程在用户态下的实际执行时间。 SIGVTALRM
ITIMER_PROF 定时进程在用户态和核心态下的实际执行时间。 SIGPROF
这三种定时器定时完成时给进程发送的信号各不相同,其中ITIMER_REAL类定时器发送SIGALRM信号,ITIMER_VIRT类定时器发送SIGVTALRM信号,ITIMER_REAL类定时器发送SIGPROF信号。
函数alarm本质上设置的是低精确、非重载的ITIMER_REAL类定时器,它只能精确到秒,并且每次设置只能产生一次定时。函数setitimer设置的定时器则不同,它们不但可以计时到微妙(理论上),还能自动循环定时。在一个Unix进程中,不能同时使用alarm和ITIMER_REAL类定时器。
SIGINT 终止进程 中断进程 (control+c)
SIGTERM 终止进程 软件终止信号
SIGKILL 终止进程 杀死进程
SIGALRM 闹钟信号
前期的知识也准备的差不多了,该向python的signal进军了。
定义信号名
signal包定义了各个信号名及其对应的整数,比如
1
2
3
|
import signal print signal.SIGALRM print signal.SIGCONT |
Python所用的信号名和Linux一致。你可以通过
1
|
$ man 7 signal |
查询
预设信号处理函数
signal包的核心是使用signal.signal()函数来预设(register)信号处理函数,如下所示:
1
|
singnal.signal(signalnum, handler) |
signalnum为某个信号,handler为该信号的处理函数。我们在信号基础里提到,进程可以无视信号,可以采取默认操作,还可以自定义操作。当handler为signal.SIG_IGN时,信号被无视(ignore)。当handler为singal.SIG_DFL,进程采取默认操作(default)。当handler为一个函数名时,进程采取函数中定义的操作。
1
2
3
4
5
6
7
8
9
|
import signal # Define signal handler function def myHandler(signum, frame): print ( 'I received: ' , signum) # register signal.SIGTSTP's handler signal.signal(signal.SIGTSTP, myHandler) signal.pause() print ( 'End of Signal Demo' ) |
在主程序中,我们首先使用signal.signal()函数来预设信号处理函数。然后我们执行signal.pause()来让该进程暂停以等待信号,以等待信号。当信号SIGUSR1被传递给该进程时,进程从暂停中恢复,并根据预设,执行SIGTSTP的信号处理函数myHandler()。myHandler的两个参数一个用来识别信号(signum),另一个用来获得信号发生时,进程栈的状况(stack frame)。这两个参数都是由signal.singnal()函数来传递的。
上面的程序可以保存在一个文件中(比如test.py)。我们使用如下方法运行:
1
|
$python test .py |
以便让进程运行。当程序运行到signal.pause()的时候,进程暂停并等待信号。此时,通过按下CTRL+Z向该进程发送SIGTSTP信号。我们可以看到,进程执行了myHandle()函数, 随后返回主程序,继续执行。(当然,也可以用$ps查询process ID, 再使用$kill来发出信号。)
(进程并不一定要使用signal.pause()暂停以等待信号,它也可以在进行工作中接受信号,比如将上面的signal.pause()改为一个需要长时间工作的循环。)
我们可以根据自己的需要更改myHandler()中的操作,以针对不同的信号实现个性化的处理。
定时发出SIGALRM信号
一个有用的函数是signal.alarm(),它被用于在一定时间之后,向进程自身发送SIGALRM信号:
1
2
3
4
5
6
7
8
9
10
11
|
import signal # Define signal handler function def myHandler(signum, frame): print ( "Now, it's the time" ) exit() # register signal.SIGALRM's handler signal.signal(signal.SIGALRM, myHandler) signal.alarm( 5 ) while True : print ( 'not yet' ) |
我们这里用了一个无限循环以便让进程持续运行。在signal.alarm()执行5秒之后,进程将向自己发出SIGALRM信号,随后,信号处理函数myHandler开始执行。
发送信号
signal包的核心是设置信号处理函数。除了signal.alarm()向自身发送信号之外,并没有其他发送信号的功能。但在os包中,有类似于linux的kill命令的函数,分别为
1
2
|
os.kill(pid, sid) os.killpg(pgid, sid) |
分别向进程和进程组(见Linux进程关系)发送信号。sid为信号所对应的整数或者singal.SIG*。
实际上signal, pause,kill和alarm都是Linux应用编程中常见的C库函数,在这里,我们只不过是用Python语言来实现了一下。实际上,Python 的解释器是使用C语言来编写的,所以有此相似性也并不意外。此外,在Python 3.4中,signal包被增强,信号阻塞等功能被加入到该包中。我们暂时不深入到该包中。
乾颐堂:http://www.qytang.com
http://www.qytang.com/cn/list/28/424.htm
http://www.qytang.com/cn/list/28/423.htm
http://www.qytang.com/cn/list/28/422.htm
http://www.qytang.com/cn/list/28/421.htm
http://www.qytang.com/cn/list/28/420.htm
http://www.qytang.com/cn/list/28/417.htm
http://www.qytang.com/cn/list/28/416.htm
http://www.qytang.com/cn/list/28/407.htm
http://www.qytang.com/cn/list/28/403.htm
http://www.qytang.com/cn/list/28/404.htm
http://www.qytang.com/cn/list/28/397.htm
http://www.qytang.com/cn/list/28/396.htm
http://www.qytang.com/cn/list/28/395.htm
http://www.qytang.com/cn/list/28/394.htm
Python使用signal模块实现定时执行的更多相关文章
- Python 信号处理 signal 模块
Table of Contents 1. signal模块简介 1.1. signal简单示例 1.2. signal说明 1.2.1. 基本的信号名 1.2.2. 常用信号处理函数 2. signa ...
- Python之signal模块的使用
常用的信号值如下: 信号值 事件 处理方式 SIGHUP 终止进程 终端线路挂断 SIGINT 终止进程 中断进程 SIGQUIT "建立CORE文件终止进程,并且生成core文件" ...
- linux下执行Python项目,crontab不能定时执行任务
问题描述: 在项目下的文件执行脚本,可以手动执行 在其他文件目录下,手动执行脚本报错误,提示不存在该模块. 解决方法: 文件头加上: import sysimport ossys.path += [ ...
- Python之signal模块
http://www.cnblogs.com/dkblog/archive/2011/03/07/1980636.html 1.超时处理 #!/usr/bin/env python2.7 #-*- c ...
- python脚本利用windows计划定时执行
- signal模块简介
signal模块简介 最近在看Linux signal 相关内容,signal可以被用来进程间通信和异步处理.Python标准库提供了signal包可以用来处理信号相关.这里讨论的是Unix系统中Py ...
- python中使用schedule模块定时执行任务
python中有一个轻量级的定时任务调度的库:schedule.他可以完成每分钟,每小时,每天,周几,特定日期的定时任务.因此十分方便我们执行一些轻量级的定时任务. 代码如下: import sche ...
- Python的定时执行
最近手把手教妹子写Python,被一篇博客误导了,这里记录一下. 妹子需要的是一个定时闹钟,到点往钉钉群里推个消息.她一顿搜索猛如虎,参照着其他人的博客,搞了一个while: target_time ...
- python定时执行详解
知识点 1. sched模块,准确的说,它是一个调度(延时处理机制),每次想要定时执行某任务都必须写入一个调度. (1)生成调度器:s = sched.scheduler(time.time,time ...
随机推荐
- Unit07: MyBatis框架简介 、 MyBatis基本应用
Unit07: MyBatis框架简介 . MyBatis基本应用 1. myBatis (1)myBatis是什么? 是一个开源的持久层框架. 注:myBatis底层仍然是jdbc. (2)编程步骤 ...
- DS02--线性表
一.PTA实验作业 题目1:线性表元素的区间删除 给定一个顺序存储的线性表,请设计一个函数删除所有值大于min而且小于max的元素.删除后表中剩余元素保持顺序存储,并且相对位置不能改变. 1. 设计思 ...
- Appium+python自动化23-Android夜神模拟器
前言 Android SDK虽然也自带了模拟器,但是那速度会让你怀疑人生,并且不稳定经常卡死异常.夜神模拟器可以说是android模拟器里面的一个神器. 环境安装 1.官网下载地址:https://w ...
- Spring不支持静态注入
在springframework里,我们不能@Autowired一个静态变量,使之成为一个spring bean,例如下面这样: @Autowired private static YourClass ...
- 使用wifi网卡笔记1----网卡选型、开发环境搭建、内核配置
1.wifi的STA模式和AP模式 Ap(Access Point)模式指的是可以将网卡设置为路由器用来共享流量或有线网络给别人使用, sta模式指的是当做网卡连接路由器上网 (1):AP也就是无线接 ...
- Vue语法
第一个Vue示例: <!DOCTYPE html> <html lang="en"> <head> <meta charset=" ...
- java中Thursday 05 September 2002类型时间的转化
package config; import Java.text.DateFormat; import java.text.ParseException; import java.text.Simpl ...
- 【转】 UML各种线的含义
原文地址:http://blog.csdn.net/jianfpeng241241/article/details/49617449 内容目录: 从一个示例开始 类之间的关系 时序图 附录:<图 ...
- python查找文件相同的和包含汉字的
#!/usr/bin/env python # Version = 3.5.2 import os import time d_path = '/data/media' log_file = 'res ...
- OpenSUSE 安装JAVA环境变量JDK
一.首先卸载虚拟机自带的JDK环境 具体命令: rpm -qa |grep java --查找java信息 rpm –qa|grep jdk --查找jdk信息 如果有依赖关系,提示无法卸载,使 ...