Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/351.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
python3 sched:在运行()之后安排事件_Python_Python 3.x - Fatal编程技术网

python3 sched:在运行()之后安排事件

python3 sched:在运行()之后安排事件,python,python-3.x,Python,Python 3.x,使用计划程序计划事件时。在调用计划程序后输入。运行直到至少触发一个在运行计划程序之前输入的事件,才会触发这些事件。这是有意的吗 import sched import threading import time now = time.time() scheduler = sched.scheduler(time.time, time.sleep) def fire(name): print('EVENT:', name, time.time() - now) def star

使用
计划程序计划事件时。在调用
计划程序后输入
。运行
直到至少触发一个在运行计划程序之前输入的事件,才会触发这些事件。这是有意的吗

import sched
import threading
import time

now = time.time()

scheduler = sched.scheduler(time.time, time.sleep)


def fire(name):
    print('EVENT:', name, time.time() - now)


def start():
    t = threading.Thread(target=scheduler.run)
    t.start()


###################################
# when scheduling all before start() everything works as expected.

# scheduler.enter(4, 1, fire, ('D',))
# scheduler.enter(3, 1, fire, ('C',))
# scheduler.enter(2, 1, fire, ('B',))
# scheduler.enter(1, 1, fire, ('A',))
# start()
#
# EVENT: A 1.0
# EVENT: B 2.0
# EVENT: C 3.0
# EVENT: D 4.0

###################################
# here I'd expect event 'A' to fire after one second. But it is
# not fired until at least one of the events scheduled before run() 
# is fired.

# scheduler.enter(2, 1, fire, ('B',))
# scheduler.enter(4, 1, fire, ('D',))
# start()
# scheduler.enter(1, 1, fire, ('A',))
# scheduler.enter(3, 1, fire, ('C',))
#
# EVENT: A 2.005021572113037
# EVENT: B 2.005021572113037
# EVENT: C 3.0050315856933594
# EVENT: D 4.0050413608551025

###################################
# starting before any event is scheduled is not possible,
# because run() returns directly.
# 
# start()
# scheduler.enter(3, 1, fire, ('C',))
# scheduler.enter(2, 1, fire, ('B',))
# scheduler.enter(1, 1, fire, ('A',))
#
# -- no events fired.

启动调度程序时,它会找到直到下一个事件的延迟,并使用该值调用delayfunc(
time.sleep()
)。在delayfunc返回之前,计划程序无法触发任何其他事件


使用
sched
模块,我看不出有什么办法可以解决这个问题。它的设计似乎基于这样一种想法,即新事件将从现有事件的处理程序中添加,而不是从单独的线程中添加(事实上,直到Python 3.3,它甚至不支持在多线程环境中使用)。使用新的
async
可能有更好的方法,但我没有任何特别的建议。

请记住,如果您可以将任务分解为定期重复的固定作业,您也可以使用
schedule

但在这种情况下,我的解决方案是将调度器子类化,如图所示,使用廉价的私有函数进行轮询。这使调度程序成为永久性的,并且它“听到”更新至少达到(至少)轮询间隔的粒度。我已经设置了一个可配置的投票率,默认为每秒4次——这对于GUI反馈很好。在生产环境中,运行的线程应该是守护进程,这样它就不会干扰终止请求。这是您的代码的修改版本。准备好使用时,从轮询中删除
打印('tick')

import sched
import threading
import time

now = time.time()

class scheduler_with_polling(sched.scheduler):
    def __init__(self, timefn, waitfn, **kwargs):
        super().__init__(timefn, waitfn)
        self.polling_interval = kwargs.get('polling_interval', 0.25)

    def run(self):
        self.enter(self.polling_interval, 1, self.__poll)
        super().run()

    def __poll(self):
        print('tick') # remove for production
        self.enter(self.polling_interval, 1, self.__poll)
        pass


scheduler = scheduler_with_polling(time.time, time.sleep, polling_interval=0.2)

def fire(name):
    print('EVENT:', name, time.time() - now)


def start():
    t = threading.Thread(target=scheduler.run) # use daemon=True for production
    t.start()

scheduler.enter(2, 1, fire, ('B',))
scheduler.enter(4, 1, fire, ('D',))
start()
scheduler.enter(1, 1, fire, ('A',))
scheduler.enter(3, 1, fire, ('C',))