Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 随时间验证连续条件_Python_Multithreading_Time_Concurrency_Python Multithreading - Fatal编程技术网

Python 随时间验证连续条件

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 #

我想开发一个python程序,从某个时刻开始,在执行某个操作之前等待60秒。程序必须具备的另一个功能是,如果我更新初始时间,它必须开始检查条件。我想用线程来做,但我不知道如何停止线程,并用新的开始时间重新开始

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)