设置定时 -- settimer
setitimer 方法也是用来定时发出 SIGALRM 信号的,但不同之处在于,他拥有更高的精度,可以定义毫秒级超时setitimer(which, seconds[, interval])
settimer 方法是另一个设置在超时时间后触发 SIGALRM 信号的方法,但与 alarm 不同,他的传入参数 seconds 可以传入小数,从而实现毫秒级超时的设置
which 参数用来指定时间的计算方式,可以选择下列三个枚举中的一个:signal.ITIMER_REAL -- 以系统真是时间来计算,触发 SIGALRM
signal.ITIMER_VIRTUAL -- 以进程用户态花费的时间计算,触发 SIGVTALRM
signal.ITIMER_PROF -- 以进程用户态和内核态所花费的时间计算,触发 SIGPROF
可选的 interval 让你可以为计时器提供一个记号,以便在 getitimer 获取到时明确是哪个计时器触发的信号即将到来
获取当前定时器 -- getitimergetitimer(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
可以看到,超时的时间是非常准确的