啟動與停止線程
- 庫可以在單獨的線程中執(zhí)行任何的在Python中可以調(diào)用的對象
import time
from threading import Thread
def countdown(n):
while n > 0:
print('T-minus', n)
n -= 1
time.sleep(1)
t = Thread(target=countdown, args=(6,))
t.start()
t.join() # 調(diào)用線程t的join()函數(shù),會把這個線程t加入到當前線程(這里就是主線程)贪婉,當前線程就會等待線程t的終止涮总,才執(zhí)行后續(xù)內(nèi)容
當你創(chuàng)建好一個線程對象后,該對象并不會立即執(zhí)行炼吴,除非你調(diào)用它的start()方法(當你調(diào)用start()方法時味滞,它會調(diào)用你傳遞進來的函數(shù),并把你傳遞進來的參 數(shù)傳遞給該函數(shù))疙挺。Python中的線程會在一個單獨的系統(tǒng)級線程中執(zhí)行(比如說一個POSIX線程或者一個Windows線程)扛邑,這些線程將由操作系統(tǒng)來全權管理。線程一旦 啟動铐然,將獨立執(zhí)行直到目標函數(shù)返回蔬崩。你可以查詢一個線程對象的狀態(tài),看它是否還在 執(zhí)行:
if t.is_alive():
print("Still running")
else:
print("Completed")
對于需要長時間運行的線程或者需要一直運行的后臺任務搀暑,你應當考慮使用后臺線程沥阳。這些線程會在主線程終止時自動銷毀。例如:
t = Thread(target=countdown, args=(6,), daemon=True)
t.start()
- 由于全局解釋鎖(GIL)的原因,Python的線程被限制到同一時刻只允許一個線 程執(zhí)行這樣一個執(zhí)行模型自点。所以桐罕, 的線程更適用于處理I/O和其他需要并發(fā)執(zhí) 行的阻塞操作(比如等待I/O、等待從數(shù)據(jù)庫獲取數(shù)據(jù)等等)桂敛,而不是需要多處理器并行的計算密集型任務功炮。
線程間通信
- 線程間數(shù)據(jù)是共享的,沒什么好說的
給關鍵部分加鎖
創(chuàng)建線程池
-
使用ThreadPoolExecutor相對于手動實現(xiàn)的好處是它使得任務提交者更方便的從被調(diào)用函數(shù)中獲取返回值术唬。
例子中返回的handle對象會幫你處理所有的阻塞與協(xié)作死宣,然后從工作線程中返回數(shù)據(jù)給你。特別的碴开, 操作會阻塞進程直到對應的函數(shù)執(zhí)行完成并返回一個 結果毅该。