python-多執行緒,python-多線程
Python多線程
Python 提供了多個模組來支援多線程編程,包括 thread、threading 和 Queue 模組等。程式是可以使用 thread 和 threading 模組來建立與管理線程。
thread 模組提供了基本的線程和鎖定支援;而 threading 模組提供了更進階別、功能更全面的線程管理。
使用 Queue 模組,使用者可以建立一個隊列資料結構,用於在多線程之間進行共用。
在python3.0中,已經將thread改名為_thread
Python 代碼的執行是由 Python 虛擬機器(又名解譯器主迴圈)進行控制的。
對 Python 虛擬機器的訪問是由全域解譯器鎖(GIL)控制的。這個鎖就是用來保證同時只能有一個線程啟動並執行。在多線程環境中,Python 虛擬機器將按照下面所述的方式執行。
1.設定 GIL。
2.切換進一個線程去運行。
3.執行下面操作之一。
a.指定數量的位元組碼指令。
b.線程主動讓出控制權(可以調用 time.sleep(0)來完成)。
4.把線程設定回睡眠狀態(切換出線程)。
5.解鎖 GIL。
6.重複上述步驟。
當一個線程完成函數的執行時,它就會退出。另外,還可以通過調用諸如 thread.exit()之類的退出函數,或者 sys.exit()之類的退出 Python 進程的標準方法,亦或者拋出 SystemExit異常,來使線程退出。不過,你不能直接“終止”一個線程。
python多線程支援的平台:
絕大多數類 UNIX 平台(如 Linux、Solaris、Mac OS X、*BSD 等),以及Windows 平台。
Python 使用相容 POSIX 的線程,也就是pthread,點擊跳轉百度百科
不使用線程的情況
我們將使用 time.sleep()函數來示範線程是如何工作的
建立兩個時間迴圈:一個睡眠 4 秒(loop0());另一個睡眠 2 秒(loop1()) (這裡使用“loop0”和“loop1”作為函數名,暗示我們最終會有一個迴圈序列)。
import timedef loop0(): print("start loop 0 at: %s" % time.ctime()) time.sleep(4) print("loop 0 done at: %s" % time.ctime())def loop1(): print("start loop 1 at: %s" % time.ctime()) time.sleep(2) print("loop 1 done at: %s" % time.ctime())def main(): print("starting at: %s" % time.ctime()) loop0() loop1() print("all DONE at: %s" % time.ctime())if __name__ == '__main__': main()
starting at: Tue Jan 23 16:03:21 2018start loop 0 at: Tue Jan 23 16:03:21 2018loop 0 done at: Tue Jan 23 16:03:25 2018start loop 1 at: Tue Jan 23 16:03:25 2018loop 1 done at: Tue Jan 23 16:03:27 2018all DONE at: Tue Jan 23 16:03:27 2018從輸出中我們可以看出,輸出整整花了我們7秒鐘的時間
單線程的輸出結果
_thread模組-一個不建議使用的模組
_thread模組和鎖對象
thread 模組的核心函數是 start_new_thread()。它的參數包括函數(對象)、函數的參數以及可選的關鍵字參數。
start_new_thread()必須包含開始的兩個參數,於是即使要執行的函數不需要參數,也需要傳遞一個空元組。
使用_thread模組進行編程:
我們只需要將上面的代碼進行稍微改動一下即可
import timeimport _threaddef loop0(): print("start loop 0 at: %s" % time.ctime()) time.sleep(4) print("loop 0 done at: %s" % time.ctime())def loop1(): print("start loop 1 at: %s" % time.ctime()) time.sleep(2) print("loop 1 done at: %s" % time.ctime())def main(): print("starting at: %s" % time.ctime()) _thread.start_new_thread(loop0, ()) _thread.start_new_thread(loop1, ()) time.sleep(5) #暫停5秒,原因是因為我們的loop0函數暫停了4秒,如果我們小於4秒會出現無法輸出loop 0 done... print("all DONE at: %s" % time.ctime())if __name__ == '__main__': main()
starting at: Tue Jan 23 16:14:19 2018start loop 0 at: Tue Jan 23 16:14:19 2018start loop 1 at: Tue Jan 23 16:14:19 2018loop 1 done at: Tue Jan 23 16:14:21 2018loop 0 done at: Tue Jan 23 16:14:23 2018all DONE at: Tue Jan 23 16:14:24 2018從輸出結果中我們可以看到loop0和loop1同時啟動了,而不會先執行完loop0在執行loop1
_thread多線程輸出結果