前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python 进程间通信(二) -- 定时信号 SIGALRM

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

作者头像
用户3147702
发布2022-06-27 13:33:02
7780
发布2022-06-27 13:33:02
举报
文章被收录于专栏:小脑斧科技博客

1. 引言

上一篇文章中我们详细介绍了 python 中的信号机制。 python 进程间通信(一) — 信号的基本使用

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

2. 秒级定时器 — alarm

UNIX 环境中有一个常用的信号 — SIGALRM,这个信号实现了进程的定时响应。 alarm 方法就是最简单的用来定时发出 SIGALRM 信号的方法。

signal.alarm(time)

2.1. 示例 — sleep 的实现

代码语言:javascript
复制
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

3. 高精度定时器 — setitimer 与 getitimer

3.1. 设置定时 — 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 获取到时明确是哪个计时器触发的信号即将到来。

3.2. 获取当前定时器 — getitimer

getitimer(which)

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

3.3. 示例 — 高精度 sleep 实现

代码语言:javascript
复制
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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-05-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 小脑斧科技博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 引言
  • 2. 秒级定时器 — alarm
    • 2.1. 示例 — sleep 的实现
    • 3. 高精度定时器 — setitimer 与 getitimer
      • 3.1. 设置定时 — settimer
        • 3.2. 获取当前定时器 — getitimer
          • 3.3. 示例 — 高精度 sleep 实现
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档