本節主要記錄如何在 Python 中使用線程,其中包括全局解釋器鎖對線程的限制和對應的學習腳本。python
Python 代碼的執行是由 Python 虛擬機(又叫解釋器主循環)進行控制的。編程
對 Python 虛擬機的訪問是由全局解釋器鎖(GIL)控制的。步驟爲:數據結構
設置 GIL;多線程
切換進一個線程去運行;函數
執行下面操做之一:oop
a. 指定數量的字節代碼指令;學習
b. 線程主動讓出控制權(能夠調用 time.sleep(0) 來完成)。spa
把線程設置回睡眠狀態(切換出線程);操作系統
解鎖 GIL;線程
重複上述步驟
當一個線程完成函數的執行時,它就會退出。
退出的方法還有:
經過調用如 thread.exit() 之類的退出函數;
如 sys.exit() 之類的退出 Python 進程的標準方法;
拋出 SystemExit 異常,來使線程退出。
不能直接「終止」一個線程;
Python 雖然支持多線程編程,可是還須要取決於它所運行的操做系統。
支持多線程的操做系統:絕大多數類 UNIX 平臺(如 Linux、Solaris、Mac OS X、*BSD等)以及 Windows 平臺;
要肯定解釋器(或者說你的系統)是否支持線程,能夠從交互式解釋器中嘗試導入 thread 模塊,若是可用則不會產生錯誤。以下:
>>> import thread
若是 Python 解釋器沒有將線程支持編譯進去,模塊導入將會失敗
>>> import thread
Traceback (most recent call last): File "<stdin>", line 1, in <module>ModuleNotFoundError: No module named 'thread'
**注:在 Python 3 中 thread 模塊被重命名爲 _thread (緣由爲日常使用不推薦用 thread 模塊,只建議那些想訪問線程的更底層級別的專家使用)。
經過一個簡單的例子代碼來演示在不使用線程的狀況下是如何工做的,方便後面對比使用線程的狀況。如下爲代碼:
1 #!/usr/bin/env python 2 3 from time import sleep, ctime 4 5 def loop0(): 6 print('start loop 0 at:', ctime()) 7 sleep(4) 8 print('loop 0 done at:', ctime()) 9 10 def loop1(): 11 print('start loop 1 at:', ctime()) 12 sleep(3) 13 print('loop 1 done at:', ctime()) 14 15 def main(): 16 print('starting at:', ctime()) 17 loop0() 18 loop1() 19 print('all DONE at:', ctime()) 20 21 if __name__ == '__main__': 22 main()
運行後的輸出結果:
1 starting at: Sun Jul 22 17:15:13 2018 2 start loop 0 at: Sun Jul 22 17:15:13 2018 3 loop 0 done at: Sun Jul 22 17:15:17 2018 4 start loop 1 at: Sun Jul 22 17:15:17 2018 5 loop 1 done at: Sun Jul 22 17:15:20 2018 6 all DONE at: Sun Jul 22 17:15:20 2018
Python 提供了多個模塊來支持多線程編程,包括 thread 、threading 和 Queue 模塊等。
thread 模塊提供了基本的線程和鎖定支持;
threading 模塊提供了更高級別、功能更全面的線程管理;
Queue 模塊能夠建立一個隊列數據結構,用於在多線程之間進行共享;
在實際進行多線程編程過程當中應該避免使用 thread 模塊:
threading 模塊更加先進、有更好的進程支持,thread 模塊中的一些熟悉會和 threading 模塊衝突;
thread 模塊擁有的同步原語註釋只有一個(同步原語用於控制執行和訪問);