社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

如何用 Python 实现优先级调度器?

Python猫 • 2 年前 • 270 次点击  

作者:kingname

来源:未闻Code

Python 自带一个调度器模块sched,它能为你实现优先级队列/延迟队列和定时队列

这个模块的使用非常简单,首先以延迟队列为例:

import sched

def do_work(name):
    print(f'你好:{name}')

sch = sched.scheduler()
sch.enter(51, do_work, argument=('kingname', ))
sch.run()

代码运行以后,会卡在sch.run()这里,5秒钟以后执行do_work('kingname'),运行效果如下图所示:

其中,sch.enter()的第一个参数为延迟的时间,单位为秒,第二个参数为优先级,数字越小优先级越高。当两个任务同时要执行时,优先级高的先执行。但需要注意的是,如果你这样写:

import sched

def do_work(name):
    print(f'你好:{name}')

sch = sched.scheduler()
sch.enter(52, do_work, argument=('产品经理', ))
sch.enter(51, do_work, argument=('kingname', ))
sch.run()

那么先打印出来的是你好:产品经理,如下图所示:

为什么这里优先级失效了?1的优先级大于2,应该先运行下面的才对啊。

这是由于,只有当两个任务同时运行的时候,才会去检查优先级。如果两个任务触发的时间一前一后,那么还轮不到比较优先级。

由于延迟队列的延迟是相对于当前运行这一行代码的时间来计算的,后一行代码比前一行代码晚了几毫秒,所以实际上产品经理这一行会先到时间,所以就会先运行。

为了使用绝对的精确时间,我们可以使用另外一个方法:

import sched
import time
import datetime

def do_work(name):
    print(f'你好:{name}')

sch = sched.scheduler(time.time, time.sleep)
start_time = datetime.datetime.now() + datetime.timedelta(seconds=10)
start_time_ts = start_time.timestamp()
sch.enterabs(start_time_ts, 2, do_work, argument=('产品经理', ))
sch.enterabs(start_time_ts, 1, do_work, argument=('kingname', ))
sch.run()

运行效果如下图所示:

sch.enterabs()的第一个参数是任务开始时间的时间戳,这是一个绝对时间,这个时间可以使用datetime模块来生成,或者其他你熟悉的方式。后面的参数和sch.enter()完全一样。

如果你要运行的函数带有多个参数或者默认参数,那么可以使用下面的方式传入参数:

import sched
import time
import datetime

def do_work(name, place, work='写代码'):
    print(f'你好:{name},你在:{place}{work}')

sch = sched.scheduler(time.time, time.sleep)
start_time = datetime.datetime.now() + datetime.timedelta(seconds=10)
start_time_ts = start_time.timestamp()
sch.enter(52, do_work, argument=('产品经理''杭州'), kwargs={'work''写需求文档'})
sch.enterabs(start_time_ts, 1, do_work, argument=('kingname''产品经理旁边'), kwargs={'work''看着她'})
sch.run()

argument参数对应的元组存放普通参数,kwargs对应的字典存放带参数名的参数。

Python猫技术交流群开放啦!群里既有国内一二线大厂在职员工,也有国内外高校在读学生,既有十多年码龄的编程老鸟,也有中小学刚刚入门的新人,学习氛围良好!想入群的同学,请在公号内回复『交流群』,获取猫哥的微信(谢绝广告党,非诚勿扰!)~


还不过瘾?试试它们




Python 为了提升性能,竟运用了共享经济

Python 中如何实现参数化测试?

为什么 Python 多线程无法利用多核?

酷炫!Python函数耗时异常自动化监控!

Python向左,数学向右:乌拉姆的素数研究

Python最会变魔术的魔术方法,我觉得是它!


如果你觉得本文有帮助
请慷慨分享点赞,感谢啦
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/113913
 
270 次点击