Python - 線程調度

你好,未來的 Python 大師!今天,我們將深入探討 Python 中的線程調度。如果你是編程新手,不必擔心;我會一步步引導你完成這次旅程,就像我多年教學中對無數學生所做的那樣。讓我們一起開啟這段激動人心的冒險吧!

Python - Thread Scheduling

理解線程

在我們進入調度之前,先來快速複習一下線程是什麼。想象一下,你在讀書的同時聽音樂。你的大腦其實是在同時運行兩個“線程”——一個用於閱讀,一個用於聽。在編程中,線程的工作方式類似,允許程序同時執行多個任務。

使用 Timer 類調度線程

現在,讓我們來探索我們的第一種調度線程的方法:Timer 類。它就像為你的代碼設定鬧鐘一樣!

Timer 類是什麼?

Timer 類是 Python 的 threading 模塊的一部分。它允許你安排一個函數在指定的延遲後運行。把它看作是告訴 Python:“嘿,幫我運行這個任務,但在開始之前先等一下!”

如何使用 Timer 類

讓我們看一個簡單的例子:

import threading
import time

def greet(name):
print(f"你好,{name}!當前時間是 {time.strftime('%H:%M:%S')}")

# 創建一個 Timer 對象
t = threading.Timer(5, greet, args=["Alice"])

# 開始計時器
t.start()

print("計時器已啟動!")

# 等待計時器完成
t.join()

print("計時器已完成!")

讓我們來分解一下:

  1. 我們導入了必要的模塊:threadingtime
  2. 我們定義了一個簡單的 greet 函數,它會打印一個帶有當前時間的問候。
  3. 我們創建了一個 Timer 對象,告訴它在 5 秒鐘延遲後運行 greet 函數,並傳遞 "Alice" 作為參數。
  4. 我們使用 t.start() 開始計時器。
  5. 我們使用 t.join() 等待計時器完成後再繼續。

當你運行這個程序時,你會立即看到 "計時器已啟動!" 的打印,然後在 5 秒鐘的暫停後,你會看到問候語,然後是 "計時器已完成!"。

取消計時器

有時,你可能需要取消已安排的任務。這就像決定你其實不需要那個鬧鐘一樣。以下是如何操作:

import threading
import time

def task():
print("這個任務不會運行!")

t = threading.Timer(5, task)
t.start()

print("計時器已啟動,但我們將取消它...")
time.sleep(2)  # 等待 2 秒鐘
t.cancel()  # 取消計時器
print("計時器已取消!")

在這個例子中,我們安排了一個任務,但在它有機會運行之前取消了它。

使用 sched 模塊調度線程

現在,讓我們提升一個等級,看看 sched 模塊。如果 Timer 類像是簡單的鬧鐘,那麼 sched 模塊就像是完整的調度應用程序!

sched 模塊是什麼?

sched 模塊允許你安排多個事件在特定時間發生。當你需要比簡單延遲更複雜的調度時,這個模塊非常完美。

如何使用 sched 模塊

讓我們看一個例子:

import sched
import time

# 創建一個調度器對象
s = sched.scheduler(time.time, time.sleep)

def print_time(name):
print(f"你好,{name}!當前時間是 {time.strftime('%H:%M:%S')}")

# 安排一些事件
s.enter(2, 1, print_time, argument=("Alice",))
s.enter(4, 2, print_time, argument=("Bob",))
s.enter(6, 3, print_time, argument=("Charlie",))

print("調度器正在啟動!")
s.run()
print("調度器已完成!")

讓我們來分解一下:

  1. 我們使用 sched.scheduler() 創建了一個調度器對象。
  2. 我們定義了一個簡單的 print_time 函數。
  3. 我們使用 s.enter() 安排三個事件:
  • 第一個參數是延遲的秒數。
  • 第二個是優先級(數字越小,優先級越高)。
  • 第三個是要運行的函數。
  • argument 鍵詞允許我們傳遞參數給函數。
  1. 我們使用 s.run() 開始調度器。

當你運行這個程序時,你會看到以 2 秒為間隔打印的問候。

取消已安排的事件

就像 Timer 一樣,你可以取消 sched 中已安排的事件:

import sched
import time

s = sched.scheduler(time.time, time.sleep)

def task(name):
print(f"你好,{name}!")

event1 = s.enter(2, 1, task, argument=("Alice",))
event2 = s.enter(4, 1, task, argument=("Bob",))

print("事件已安排。正在取消 Bob 的事件...")
s.cancel(event2)

s.run()
print("調度器已完成!")

在這個例子中,我們安排了兩個事件,但在運行調度器之前取消了第二個。

Timer 和 sched 的比較

以下是這兩種方法的快速比較:

特性 Timer sched
易用性 簡單,直觀 更複雜,但功能更強大
多個事件 一次一個 可以安排多個事件
精確度 精確度較低 精確度較高
取消 可以在執行前取消 可以在任何時間取消
使用案例 簡單延遲 複雜調度需求

結論

就是這樣,各位!我們已經走過了 Python 中線程調度的世界,從簡單的 Timer 類到更複雜的 sched 模塊。請記住,就像學習騎自行車一樣,掌握這些概念需要練習。所以不要害怕實驗和犯錯——這是我們學習的方式!

在我的教學生涯中,我見證了學生們從完全的新手變成了 Python 專家,我相信你也可以做到。繼續編程,繼續學習,最重要的是,享受其中的樂趣!

下次見,快樂編程!

Credits: Image by storyset