ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python中的快速方法调用调度

2019-11-06 16:05:24  阅读:227  来源: 互联网

标签:multithreading scheduling timer linux 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()方法及早唤醒调度线程.

标签:multithreading,scheduling,timer,linux,python
来源: https://codeday.me/bug/20191106/1999557.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有