当前位置:天才代写 > tutorial > Python教程 > Python利用signal模块实现按时执行

Python利用signal模块实现按时执行

2017-11-02 08:00 星期四 所属: Python教程 浏览:630

在liunx系统中要想每隔一分钟执行一个呼吁,最普遍的要领就是crontab了,假如不想利用crontab,经同事指点在措施中可以用按时器实现这种成果,于是就开始探索了,发明需要一些信号的常识…

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

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包界说了各个信号名及其对应的整数,好比

import signal
print signal.SIGALRM
print signal.SIGCONT

Python所用的信号名和Linux一致。你可以通过

$man 7 signal

查询

预设信号处理惩罚函数

signal包的焦点是利用signal.signal()函数来预设(register)信号处理惩罚函数,如下所示:

singnal.signal(signalnum, handler)

#p#分页标题#e#

signalnum为某个信号,handler为该信号的处理惩罚函数。我们在信号基本里提到,历程可以无视信号,可以采纳默认操纵,还可以自界说操纵。当handler为signal.SIG_IGN时,信号被无视(ignore)。当handler为singal.SIG_DFL,历程采纳默认操纵(default)。当handler为一个函数名时,历程采纳函数中界说的操纵。

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)。我们利用如下要领运行:

$python test.py

以便让历程运行。当措施运行到signal.pause()的时候,历程暂停并期待信号。此时,通过按下CTRL+Z向该历程发送SIGTSTP信号。我们可以看到,历程执行了myHandle()函数, 随后返回主措施,继承执行。(虽然,也可以用$ps查询process ID, 再利用$kill来发出信号。)

(历程并不必然要利用signal.pause()暂停以期待信号,它也可以在举办事情中接管信号,好比将上面的signal.pause()改为一个需要长时间事情的轮回。)

我们可以按照本身的需要变动myHandler()中的操纵,以针对差异的信号实现本性化的处理惩罚。

按时发出SIGALRM信号

一个有用的函数是signal.alarm(),它被用于在一按时间之后,向历程自身发送SIGALRM信号:

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呼吁的函数,别离为

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包被加强,信号阻塞等成果被插手到该包中。我们临时不深入到该包中。

 

    关键字:

天才代写-代写联系方式