"sched" --- 事件排程器
**********************

**原始碼：**Lib/sched.py

======================================================================

"sched" 模組定義了一個有實作通用事件排程器的類別：

class sched.scheduler(timefunc=time.monotonic, delayfunc=time.sleep)

   "scheduler" 類別定義了事件排程的泛用介面。它需要兩個函式來和「外部
   世界」作用 —— *timefunc* 應不帶引數地被呼叫，並回傳一個數字（為「時
   間」，可為任何單位）。*delayfunc* 函式應以一個引數呼叫，並與
   *timefunc* 的輸出相容，且應延遲其指定的時間單位。每個事件運行後，也
   會以引數 "0" 呼叫 *delayfunc*，來使得其他執行緒有機會在多執行緒應用
   程式中運行。

   在 3.3 版的變更: *timefunc* 和 *delayfunc* 參數是可選的。

   在 3.3 版的變更: "scheduler" 類別可以安全地在多執行緒環境中使用。

範例：

   >>> import sched, time
   >>> s = sched.scheduler(time.time, time.sleep)
   >>> def print_time(a='default'):
   ...     print("From print_time", time.time(), a)
   ...
   >>> def print_some_times():
   ...     print(time.time())
   ...     s.enter(10, 1, print_time)
   ...     s.enter(5, 2, print_time, argument=('positional',))
   ...     # 儘管優先順序較高，但由於 enter() 是相對的，'keyword' 在 'positional' 之後運行
   ...     s.enter(5, 1, print_time, kwargs={'a': 'keyword'})
   ...     s.enterabs(1_650_000_000, 10, print_time, argument=("first enterabs",))
   ...     s.enterabs(1_650_000_000, 5, print_time, argument=("second enterabs",))
   ...     s.run()
   ...     print(time.time())
   ...
   >>> print_some_times()
   1652342830.3640375
   From print_time 1652342830.3642538 second enterabs
   From print_time 1652342830.3643398 first enterabs
   From print_time 1652342835.3694863 positional
   From print_time 1652342835.3696074 keyword
   From print_time 1652342840.369612 default
   1652342840.3697174


排程器物件
==========

"scheduler" 實例具有以下方法和屬性：

scheduler.enterabs(time, priority, action, argument=(), kwargs={})

   為一個新事件排程。*time* 引數應該是與傳遞給建構函式的 *timefunc* 函
   式回傳值相容的數字型別。安排在相同 *time* 的事件將按照其 *priority*
   的順序執行。數字越小代表優先順序越高。

   執行事件意味著執行 "action(*argument, **kwargs)"。*argument* 是一個
   包含 *action* 之位置引數的序列。*kwargs* 是一個字典，帶有 *action*
   的關鍵字引數。

   回傳值是一個事件，可用於後續取消該事件（請見 "cancel()"）。

   在 3.3 版的變更: *argument* 參數是可選的。

   在 3.3 版的變更: 新增 *kwargs* 參數。

scheduler.enter(delay, priority, action, argument=(), kwargs={})

   為一個排程事件延期 *delay* 個時間單位。除了相對時間之外，其他引數、
   效果和回傳值皆與 "enterabs()" 的相同。

   在 3.3 版的變更: *argument* 參數是可選的。

   在 3.3 版的變更: 新增 *kwargs* 參數。

scheduler.cancel(event)

   從佇列中刪除該事件。如果 *event* 不是目前佇列中的事件，此方法將引發
   "ValueError"。

scheduler.empty()

   如果事件佇列為空，則回傳 "True"。

scheduler.run(blocking=True)

   運行所有已排程的事件。此方法將會等待（使用傳遞給建構函式的
   *delayfunc* 函式）下一個事件，然後執行它，並依此類推，直到不再有排
   程好的事件。

   如果 *blocking* 為 false，則執行最快到期的已排程事件（如存在），然
   後回傳排程器中下一個排程呼叫（如存在）的截止時間。

   *action* 或 *delayfunc* 都可能引發例外。無論哪種情況，排程器都將保
   持一致的狀態並傳遞例外。如果是由 *action* 引發例外，則後續呼叫
   "run()" 時將不會嘗試運行該事件。

   如果一系列事件的運行時長比執行下一個事件前的可用時長 (available
   time) 更長，那麼排程器就單純會落後。不會有事件被丟棄；呼叫程式碼也
   要負責取消不再相關的事件。

   在 3.3 版的變更: 新增 *blocking* 參數。

scheduler.queue

   會按事件運行順序回傳即將發生的事件串列的唯讀屬性。每個事件都以*附名
   元組 (named tuple)* 表示，並包含以下欄位：時間、優先順序、動作
   (action)、引數、kwargs。
