一日一技:Python自帶的優先級調度器

一日一技:Python自帶的優先級調度器

一日一技:Python自帶的優先級調度器

Python 自帶一個調度器模塊 sched,它能爲你實現優先級隊列/延遲隊列和定時隊列。ide

這個模塊的使用很是簡單,首先以延遲隊列爲例:函數

import sched
def do_work(name):
print(f'你好:{name}')
sch = sched.scheduler()
sch.enter(5, 1, do_work, argument=('kingname', ))
sch.run()

代碼運行之後,會卡在 sch.run()這裏,5秒鐘之後執行 do_work('kingname'),運行效果以下圖所示:
一日一技:Python自帶的優先級調度器
其中, sch.enter()的第一個參數爲延遲的時間,單位爲秒,第二個參數爲優先級,數字越小優先級越高。當兩個任務同時要執行時,優先級高的先執行。但須要注意的是,若是你這樣寫:code

import sched
def do_work(name):
print(f'你好:{name}')
sch = sched.scheduler()
sch.enter(5, 2, do_work, argument=('產品經理', ))
sch.enter(5, 1, do_work, argument=('kingname', ))
sch.run()

那麼先打印出來的是 你好:產品經理,以下圖所示:
一日一技:Python自帶的優先級調度器blog

爲何這裏優先級失效了?1的優先級大於2,應該先運行下面的纔對啊。隊列

這是因爲,只有當兩個任務同時運行的時候,纔會檢查優先級。若是兩個任務觸發的時間一前一後,那麼還輪不到比較優先級。因爲延遲隊列的 延遲是相對於當前運行這一行代碼的時間來計算的,後一行代碼比前一行代碼晚了幾毫秒,因此實際上產品經理這一行會先到時間,因此就會先運行。文檔

爲了使用絕對的精確時間,咱們能夠使用另一個方法:產品

import sched
import time
import datetime
def do_work(name):
print(f'你好:{name}')
sch = sched.scheduler(time.time, time.sleep)
start_ime = 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()

運行效果以下圖所示:
一日一技:Python自帶的優先級調度器it

sch.enterabc()的第一個參數是任務開始時間的時間戳,這是一個絕對時間,這個時間能夠使用datetime模塊來生成,或者其餘你熟悉的方式。後面的參數和 sch.enter()徹底同樣。class

若是你要運行的函數帶有多個參數或者默認參數,那麼能夠使用下面的方式傳入參數:import

import schedimport 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(5, 2, do_work, argument=('產品經理', '杭州'), kwargs={'work': '寫需求文檔'})
sch.enterabs(start_time_ts, 1, do_work, argument=('kingname', '產品經理旁邊'), kwargs={'work': '看着她'})
sch.run()
.

argument參數對應的元組存放普通參數,kwargs對應的字典存放帶參數名的參數。

相關文章
相關標籤/搜索