python 进程间通信(二) -- 定时信号 SIGALRM

2019-05-30 11:22:09   最后更新: 2019-05-30 11:22:09   访问数量:168




上一篇文章中我们详细介绍了 python 中的信号机制

python 进程间通信(一) -- 信号的基本使用

 

我们了解了最基本的信号处理和响应,本文我们来详细介绍一下信号系统另一十分重要的功能 -- 定时响应的信号 SIGALARM

 

 

UNIX 环境中有一个常用的信号 -- SIGALRM,这个信号实现了进程的定时响应

alarm 方法就是最简单的用来定时发出 SIGALRM 信号的方法

signal.alarm(time)

 

示例 -- sleep 的实现

import logging import signal def alarmhandler(signum, frame): ... def sleep(nsec): signal.pthread_sigmask(signal.SIG_UNBLOCK, {signal.SIGALRM}) signal.signal(signal.SIGALRM, alarmhandler) signal.alarm(nsec) signal.pause() if __name__ == '__main__': logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') logging.info('main start sleep') sleep(3) logging.info('main after sleep')

 

 

执行程序,打印出了:

2019-05-29 21:20:10,163 - INFO: main start sleep

2019-05-29 21:20:13,164 - INFO: main after sleep

 

设置定时 -- settimer

setitimer 方法也是用来定时发出 SIGALRM 信号的,但不同之处在于,他拥有更高的精度,可以定义毫秒级超时

setitimer(which, seconds[, interval])

 

settimer 方法是另一个设置在超时时间后触发 SIGALRM 信号的方法,但与 alarm 不同,他的传入参数 seconds 可以传入小数,从而实现毫秒级超时的设置

which 参数用来指定时间的计算方式,可以选择下列三个枚举中的一个:

  1. signal.ITIMER_REAL -- 以系统真是时间来计算,触发 SIGALRM
  2. signal.ITIMER_VIRTUAL -- 以进程用户态花费的时间计算,触发 SIGVTALRM
  3. signal.ITIMER_PROF -- 以进程用户态和内核态所花费的时间计算,触发 SIGPROF

 

可选的 interval 让你可以为计时器提供一个记号,以便在 getitimer 获取到时明确是哪个计时器触发的信号即将到来

 

获取当前定时器 -- getitimer

getitimer(which)

 

与 setitimer 相对应,getitimer 用来实现获取定时器情况,他返回一个拥有两个元素的元组,第一个元素是距离定时器下一次触发剩余的超时时间,第二个元素则是创建定时器时可选的 interval 参数的值

which 参数的取值与含义和 setitimer 完全一致

 

示例 -- 高精度 sleep 实现

import logging import signal def alarmhandler(signum, frame): logging.info('%s handled' % signum) def sleep(nsec): signal.pthread_sigmask(signal.SIG_UNBLOCK, {signal.SIGALRM}) signal.signal(signal.SIGALRM, alarmhandler) signal.setitimer(signal.ITIMER_REAL, nsec) logging.info(signal.getitimer(signal.ITIMER_REAL)) signal.pause() if __name__ == '__main__': logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') logging.info('main start sleep') sleep(1.2) logging.info('main after sleep')

 

 

上面的代码实现了 sleep 1.2 秒的毫秒级超时 sleep,打印出了

2019-05-30 08:11:45,580 - INFO: main start sleep

2019-05-30 08:11:45,580 - INFO: (1.199995, 0.0)

2019-05-30 08:11:46,781 - INFO: 14 handled

2019-05-30 08:11:46,781 - INFO: main after sleep

 

可以看到,超时的时间是非常准确的

 

欢迎关注微信公众号,以技术为主,涉及历史、人文等多领域的学习与感悟,每周三到七篇推文,全部原创,只有干货没有鸡汤

 

 






技术帖      python      进程间通信      ipc      signal      信号      sigalrm     


京ICP备15018585号