Python 随时间验证连续条件
我想开发一个python程序,从某个时刻开始,在执行某个操作之前等待60秒。程序必须具备的另一个功能是,如果我更新初始时间,它必须开始检查条件。我想用线程来做,但我不知道如何停止线程,并用新的开始时间重新开始Python 随时间验证连续条件,python,multithreading,time,concurrency,python-multithreading,Python,Multithreading,Time,Concurrency,Python Multithreading,我想开发一个python程序,从某个时刻开始,在执行某个操作之前等待60秒。程序必须具备的另一个功能是,如果我更新初始时间,它必须开始检查条件。我想用线程来做,但我不知道如何停止线程,并用新的开始时间重新开始 import thread import time # Define a function for the thread def check_message (last, timer): oldtime = time.time() print oldtime #
import thread
import time
# Define a function for the thread
def check_message (last, timer):
oldtime = time.time()
print oldtime
# check
while time.time() - oldtime <= 60:
print (time.time() - oldtime)
print "One minute"+ str(time.time())
return 1
# Create two threads as follows
try:
named_tuple = time.localtime() # get struct_time
time_string = time.strftime("%H:%M:%S", named_tuple)
thread.start_new_thread(check_message , (time_string, 60))
except:
print "Error: unable to start thread"
while 1:
pass
导入线程
导入时间
#为线程定义一个函数
def check_消息(最后一个,计时器):
oldtime=time.time()
打印旧版本
#检查
而time.time()-oldtime一个选项是在线程外执行检查,以便主循环每60秒执行一个线程,该线程执行X作业:
import threading
import time
# Define a function for the thread
def check_message():
print("One minute"+ str(time.time()))
return 1
last_execution = time.time()
while 1:
if time.time() - last_execution < 60:
time.sleep(1)
else:
last_execution = time.time()
threading.Thread(target=check_message).start()
# Python2:
# import thread
# thread.start_new_thread(check_message)
导入线程
导入时间
#为线程定义一个函数
def check_消息():
打印(“一分钟”+str(time.time()))
返回1
上次执行=time.time()
而1:
如果time.time()-上次执行<60:
时间。睡眠(1)
其他:
上次执行=time.time()
threading.Thread(target=check_message).start()
#蟒蛇2:
#导入线程
#线程。启动新线程(检查消息)
由于没有安装Python2,我将代码替换为在Python3中工作的语法。但是在这两个版本中,总体思路应该是相同的。在循环中检查时间在这里可能没有必要,而且是浪费,因为您可以让线程进入睡眠状态,如果时间到了,让内核唤醒它。
线程库提供了这样的用例。本例中的困难在于,您不能中断此类休眠线程来调整执行指定函数的间隔
在下面的示例中,我使用了一个自定义管理器类TimeLord
,以克服这个限制TimeLord
通过取消当前计时器并将其替换为新计时器来启用“重置”计时器。
为此,TimeLord
包含一个包装中间工作函数和一个“token”属性,运行计时器实例必须弹出该属性以执行指定的目标函数
由于dict.pop()
是一种原子操作,这种设计保证了指定目标函数的唯一执行timelord.reset()
只要当前计时器尚未启动其线程并弹出\u令牌
就有效。在尝试“重置”时,这种方法不能完全防止新计时器线程的潜在无效启动,但由于目标函数只能执行一次,因此在发生这种情况时,它是一种非关键冗余
此代码使用Python 2和3运行:
import time
from datetime import datetime
from threading import Timer, current_thread
def f(x):
print('{} {}: RUNNING TARGET FUNCTION'.format(
datetime.now(), current_thread().name)
)
time.sleep(x)
print('{} {}: EXITING'.format(datetime.now(), current_thread().name))
class TimeLord:
"""
Manager Class for threading.Timer instance. Allows "resetting" `interval`
as long execution of `function` has not started by canceling the old
and constructing a new timer instance.
"""
def worker(self, *args, **kwargs):
try:
self.__dict__.pop("_token") # dict.pop() is atomic
except KeyError:
pass
else:
self.func(*args, **kwargs)
def __init__(self, interval, function, args=None, kwargs=None):
self.func = function
self.args = args if args is not None else []
self.kwargs = kwargs if kwargs is not None else {}
self._token = True
self._init_timer(interval)
def _init_timer(self, interval):
self._timer = Timer(interval, self.worker, self.args, self.kwargs)
self._timer.daemon = True
def start(self):
self._timer.start()
print('{} {}: STARTED with `interval={}`'.format(
datetime.now(), self._timer.name, self._timer.interval)
)
def reset(self, interval):
"""Cancel latest timer and start a new one if `_token` is still there.
"""
print('{} {}: CANCELED'.format(datetime.now(), self._timer.name))
self._timer.cancel()
# reduces, but doesn't prevent, occurrences when a new timer
# gets created which eventually will not succeed in popping
# the `_token`. That's uncritical redundancy when it happens.
# Only one thread ever will be able to execute `self.func()`
if hasattr(self, "_token"):
self._init_timer(interval)
self.start()
def cancel(self):
self._timer.cancel()
def join(self, timeout=None):
self._timer.join(timeout=timeout)
示例输出:
***初始间隔为5的测试***
2019-06-05 20:58:23.448404线程-1:以“间隔=5”开始`
***2019-06-05 20:58:23.448428睡两秒钟***
2019-06-05 20:58:25.450483线程-1:取消
2019-06-05 20:58:25.450899螺纹-2:以“间隔=6”开始`
2019-06-05 20:58:25.450955螺纹-2:取消
2019-06-05 20:58:25.451496螺纹-3:以“间隔=7”开始`
2019-06-05 20:58:32.451592线程-3:运行目标函数
2019-06-05 20:58:42.457527螺纹-3:退出
----------------------------------------------------------------------
***初始间隔为2的测试***
2019-06-05 20:58:42.457986螺纹-4:以“间隔=2”开始`
***2019-06-05 20:58:42.458033睡眠两秒***
2019-06-05 20:58:44.458058线程-4:运行目标函数
2019-06-05 20:58:44.459649线程-4:取消
2019-06-05 20:58:44.459724线程-4:取消
2019-06-05 20:58:54.466342螺纹-4:退出
----------------------------------------------------------------------
进程已完成,退出代码为0
注意,当interval=2时,两秒钟后的取消没有效果,因为计时器已经在执行目标函数
def run_demo(initial_interval):
print("*** testing with initial interval {} ***".format(initial_interval))
tl = TimeLord(interval=initial_interval, function=f, args=(10,))
tl.start()
print('*** {} sleeping two seconds ***'.format(datetime.now()))
time.sleep(2)
tl.reset(interval=6)
tl.reset(interval=7)
tl.join()
print("-" * 70)
if __name__ == '__main__':
run_demo(initial_interval=5)
run_demo(initial_interval=2)