python threading.timer 查看是否活跃_如何获得相当于使用系统正常运行时间的Python threading.Timer?...

timer使用系统时间,但在我使用它时时间会发生变化,我如何才能让它使用系统正常运行时间?

我有一个python脚本,它可以做很多事情,其中之一就是设置系统时间。当这个脚本启动时,时间是错误的。此脚本还需要30秒的全局超时。

我一直在使用以下超时类:

class Timeout(object):

def __init__(self, seconds=1, signum=signal.SIGUSR1, exception=TimeoutException):

self.exception = exception

self.pid = os.getpid()

self.signum = signum

self.timer = threading.Timer(seconds, self.exit_function)

def exit_function(self):

os.kill(self.pid, self.signum)

def handle_timeout(self, signum, frame):

raise self.exception()

def __enter__(self):

signal.signal(self.signum, self.handle_timeout)

self.timer.start()

def __exit__(self, type, value, traceback):

self.timer.cancel()

它包装了我的整个脚本:

with Timeout(seconds=30):

main()

有时脚本会很快失败,或者在30秒后永远不会被杀死。我认为这是因为threading.Timer使用了在脚本运行时更改的系统时间。我能让它使用系统正常运行时间吗?

如何在python中实现看门狗计时器的可能副本?

不是重复的,所有这些例子都使用系统时间,我想使用系统正常运行时间,就像是/proc/uptime一样。

threading.Timer是基于条件锁的,基于一个单调的计时器,它说:时钟不受系统时钟更新的影响。所以这不是你的问题。你不需要系统正常运行时间-你已经准备好独立的时间了

嗯,我在运行Debian Linux 3.10.103-marvell armv7l GNU/Linux和python 2.7.9。如果我改变时间,它会影响到Event.interval内部的threading.Timer调用。

是的,刚刚发现你可能有Python<3.3。有趣的话题。在给定的答案中,我可能会有一个方法。编辑:哦,废话-你用的是Linux

我最终扩展了threading.Timer以使用系统正常运行时间。

class Timer(threading._Timer):

def __init__(self, *args, **kwargs):

super(Timer, self).__init__(*args, **kwargs)

# only works on Linux

self._libc = ctypes.CDLL('libc.so.6')

self._buf = ctypes.create_string_buffer(128)

def uptime(self):

self._libc.sysinfo(self._buf)

return struct.unpack_from('@l', self._buf.raw)[0]

def run(self):

start_time = self.uptime()

while not self.finished.is_set():

time.sleep(0.1)

if self.uptime() - start_time > self.interval:

self.function(*self.args, **self.kwargs)

break

self.finished.set()

似乎您使用的是python<3.3。在python 3.3或更新版本上,monotonic将是标准库中time.monotonic的别名。当时,time.monotonic也用于threadinglibary。如文件所述:

Return the value (in fractional seconds) of a monotonic clock, i.e. a clock that cannot go backwards. The clock is not affected by system clock updates.

因此,使用python>=3.3,threading.Timer将是独立的。

尝试解决您的问题:窗户

我看到一种选择,可以使用gettickcount从使用ctypes的kernel32.dll获得所需的系统正常运行时间:

import ctypes

kernel_32 = ctypes.cdll.LoadLibrary("Kernel32.dll")

kernel_32.GetTickCount()  # overflow after 49.7 days

kernel_32.GetTickCount64()

有了这个,你就可以用一些不好用的东西来创建你自己的计时器,比如:

def sleep(time):

start = kernel_32.GetTickCount64()

end = start + time

while kernel_32.GetTickCount64() < end:

pass

print('done')

我真的希望这种方法有助于解决你的问题-祝你好运

编辑:Linux

基于单调:您可以尝试将其作为gettickCount1的替代方法:

try:

clock_gettime = ctypes.CDLL(ctypes.util.find_library('c'), use_errno=True).clock_gettime

except Exception:

clock_gettime = ctypes.CDLL(ctypes.util.find_library('rt'), use_errno=True).clock_gettime

class timespec(ctypes.Structure):

"""Time specification, as described in clock_gettime(3)."""

_fields_ = (('tv_sec', ctypes.c_long), ('tv_nsec', ctypes.c_long))

if sys.platform.startswith('linux'):

CLOCK_MONOTONIC = 1

elif sys.platform.startswith('freebsd'):

CLOCK_MONOTONIC = 4

elif sys.platform.startswith('sunos5'):

CLOCK_MONOTONIC = 4

elif 'bsd' in sys.platform:

CLOCK_MONOTONIC = 3

elif sys.platform.startswith('aix'):

CLOCK_MONOTONIC = ctypes.c_longlong(10)

def monotonic():

"""Monotonic clock, cannot go backward."""

ts = timespec()

if clock_gettime(CLOCK_MONOTONIC, ctypes.pointer(ts)):

errno = ctypes.get_errno()

raise OSError(errno, os.strerror(errno))

return ts.tv_sec + ts.tv_nsec / 1.0e9

1:版权所有2014、2015、2016 Ori Livneh根据Apache许可证2.0版(以下简称"许可证")获得许可;除非符合许可证,否则您不能使用此文件。您可以在以下网址获得许可证副本:http://www.apache.org/licenses/license-2.0除非适用法律要求或书面同意,软件根据许可证分发是按"原样"分发的,无任何明示或暗示的保证或条件。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值