Python中的快速方法调用调度

对于项目的某些部分,我需要一个本地过程调度系统,该系统可使我将方法执行延迟几秒钟.我有数千个该系统的“客户端”,因此使用threading.Timer进行每个延迟都是一个坏主意,因为我将很快达到OS线程限制.我有implemented个系统,该系统仅使用一个线程进行定时控制.

主要思想是保持已排序的任务(时间函数args kwargs)队列并使用单线程.计时器可调度/取消此队列头的执行.该方案有效,但是我对性能不满意.每2000〜10个客户端每10秒安排一次虚拟任务,导致该进程占用40%的CPU时间.查看事件探查器的输出,我发现所有时间都花在了新线程上,计时器的构造,开始以及特别是在新线程的创建上.

我相信有更好的方法.现在,我考虑重写LightTimer,以便有一个可由threading.Event控制的执行线程和几个set()事件的计时线程.例如:

>我计划在10秒内调用一个任务.该任务已添加到队列中.计时线程1在event.set()之前开始time.sleep(10)
>然后我安排一个任务在11秒内调用.任务已添加到队列中.定时线程什么也没有发生,它会在唤醒后注意到新任务.
>然后我安排一个任务在5秒钟内调用.任务被添加到队列中.定时线程2开始time.sleep(5),因为#1已经睡眠了更长的时间间隔.

希望您能理解.您如何看待这种方式?有没有更好的办法?也许我可以利用某些Linux系统功能来制定最佳解决方案?

解决方法:

您可以使用的另一种实现方式是使用time.time()方法来计算每个排队函数应执行的绝对时间.将这段时间和要调用的函数放在一个对象包装中,该包装将使用执行时间来确定顺序来覆盖比较运算符.然后使用heapq模块维护最小堆.这将为您提供有效的数据结构,其中堆元素0始终是您的下一个事件.

实现实际调用的一种方法是使用单独的线程执行回调.堆将需要使用互斥锁进行保护,并且您可以使用条件变量来实现调度.在无限循环中,只需查找下一次执行函数(堆的元素0),然后使用条件变量的wait()方法,并将超时设置为下一次执行时间.如果新插入的函数应该在堆中最早出现的函数之前发生,则您的堆插入方法可以使用条件变量的notify()方法及早唤醒调度线程.

上一篇:c – 对OpenMP中静态调度开销的影响


下一篇:在Spring中使用相同的工作详细信息动态地重新计划CronTriggerBean