Python使用signal模块实现定时执行

在liunx系统中要想每隔一分钟执行一个命令,最普遍的方法就是crontab了,如果不想使用crontab,经同事指点在程序中可以用定时器实现这种功能,于是就开始摸索了,发现需要一些信号的知识...

查看你的linux支持哪些信号:kill -l 即可


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

[email protected]:~# 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

[email protected]:~#

信号:进程之间通讯的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。操作系统规定了进程收到信号以后的默认行为,但是,我们可以通过绑定信号处理函数来修改进程收到信号以后的行为,有两个信号是不可更改的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

时间: 2024-10-19 15:06:18

Python使用signal模块实现定时执行的相关文章

linux下执行Python项目,crontab不能定时执行任务

问题描述: 在项目下的文件执行脚本,可以手动执行 在其他文件目录下,手动执行脚本报错误,提示不存在该模块. 解决方法: 文件头加上: import sysimport ossys.path += [ os.path.dirname(os.getcwd()), os.getcwd() ]curPath = os.path.abspath(os.path.dirname(__file__))rootPath = os.path.split(curPath)[0]sys.path.append(roo

python脚本利用windows计划定时执行

使用signal模块为异步事件设置handlers

python的signal模块提供机制由于signal handlers.使用signals和它们的handlers有以下准则:

使用sae定时执行Python脚本

使用sae定时执行Python脚本 使用sae定时执行Python脚本 12,May,2014 | 57 Views 毕设压力略大,必须是桂林游的锅.去之前放松了几天,回来又休闲了几天,加上桂林的一周,半个月直接没了.中午忙里偷闲尝试了下sae,出了这么久才开始用,真是捉急. 今天的目标是要让自己的微博能够整点报时.功能其实很简单,发微博的api新浪全都提供了.你甚至可以直接写段脚本,开着电脑让它一直跑,但这样太low了,尽管用sae服务的原理也是一样.使用sae定时执行Python脚本,布布扣

快速低成本在新浪云SAE上建立定时执行任务 -以python脚本为例

1解决的问题和优势 l 利用SAE云应用不间断在线的特点,支持定时执行任务,支持php.java.python2.7等语言运行,从此不用担心自己的电脑关机了,没网络了不能及时有效运行定时任务的尴尬,当然也可以部署其他自己或SAE提供的应用(收费了,与其他云平台区别不大) l 对于一些小脚本的定时运行基本可以做到免费,代码空间5G,存储空间10G,可以支持小爬虫定时采集网页,自动发微博,帖子等各种有趣的功能 l 使用较为简单,上手容易,文档帮助齐全,可以快速使用 2 建立自己的定时运行应用 ...

python导入模块时的执行顺序

当python导入模块,执行import语句时,到底进行了什么操作?按照python的文档,她执行了如下的操作: 第一步,创建一个新的module对象(它可能包含多个module) 第二步,把这个module对象插到sys.module中 第三步,装载module的代码(如果需要,则必须先编译) 第四步,执行新的module中对应的代码. 在执行第三步时,首先需要找到module程序所在的位置,搜索的顺序是: 当前路径(以及从当前目录指定的sys.path),pythonpath,然后是pyth

操作系统定期定时执行python脚本

1. Windows 控制面板 --> 管理工具 -->任务计划程序 --> 创建任务 接下来就是设置执行的时机以及脚本路径等 1>>常规 设置任务名称描述,以及是否执行时候需要登录等. 2>>触发器 触发器指定什么时候执行,是只执行一次还是重复执行. 3>>操作 操作设置要执行的任务是什么,我们要执行的任务是定时执行我们的python脚本,这里注意红色框圈起来的地方,不要搞反了. 2. linux系统 at和crontab命令

python标准库介绍——37 signal 模块详解

==signal 模块== 你可以使用 ``signal`` 模块配置你自己的信号处理器 (signal handler), 如 [Example 3-11 #eg-3-11] 所示. 当解释器收到某个信号时, 信号处理器会立即执行. ====Example 3-11. 使用 signal 模块====[eg-3-11] ``` File: signal-example-1.py import signal import time def handler(signo, frame): print

python定时执行方法

1  time.sleep import time for i in range(5): print(i) time.sleep(10) 2 用shed import time import sched schedule = sched.scheduler ( time.time, time.sleep ) def func(string1,float1): print("now is",time.time()," | output=",string1,float1