本文實例講述了Python多線程及其基本使用方法。分享給大家供大家參考,具體如下:
學習Python的多線程(Multi-threading),至少應該要有進程與線程的基本概念,可以參考:http://www.ruanyifeng.com/blog/2013/04/processes_and_threads.html。
1.Python中的多線程
執行一個程序,即在操作系統中開啟了一個進程,在某一時刻,一個CPU內核只能進行一個進程的任務,現在的計算機所說的多進程/多任務其實是通過加快CPU的執行速度來實現的,因為一個CPU每秒能執行上億次的計算,能夠對進程進行很多次切換,所以在人為可以感知的時間里,看上去,計算機確實是在同時執行多個程序,即同時處理多個進程。
一個進程中可以包含有多個線程,這多個線程為實現該進程的某個主要功能而運行著,多個線程可以進行串行工作,也可以并發同時進行工作,顯然后者可以節省更多的時間。
在Python中是支持多線程并發執行的,只是Python中的多線程只能利用單核,也就是說Python中的某一個進程的多個線程只能在一個CPU核心上運行,而不能分配在多個CPU核心中運行,這是考慮到線程安全的緣故,而Python中的GIL則保證了線程安全。關于Python中的GIL,可以參考下面一篇文章:《淺析Python的GIL和線程安全》。
下面是自己在學習過程中的一些課堂筆記,因為還沒有真正學習一些理論,所以可能會有些錯誤,但目前是方便自己的理解:
即GLI是以CPU核心為單位來控制全局鎖,所以是不能跨不同的CPU(核心 )的GLI可以保證同一個進程中,某一個線程的共享數據在某一時刻只能同時被另外一個線程修改(使用),而不能同時被多個線程修改(使用),如果去掉GLI,則需要自己為線程加鎖,這樣之后,性能比原來還要差。
當然,難道就不能充分利用多核CPU或多個CPU了?
做成多進程就可以了,不同的進程運行在不同的CPU(核心)上,也可以實現并發,只是這樣的話就會比較浪費內存空間,考慮同時運行10個QQ程序的情況,假如1個QQ占用500M的內存空間,則10個QQ就要占用5G的內存空間了。但如果是多線程的話,可能10個QQ還是共享著這500M的內存空間。還有一個缺點就是,多進程間的數據直接訪問可能會比較麻煩,但其實也是可以實現的,比如chrome瀏覽器就是用多進程實現的。
目前首先要明確的是,Python中是不能把一個進程的多個線程分布在不同的CPU核心上運行的。
2.Python多線程使用方法1
給出下面的程序代碼及注釋:
import threading #Python多線程模塊 import time def run(num): print 'Hi, I am thread %s..lalala' % num time.sleep(1) for i in range(20): t = threading.Thread(target=run, args=(i,)) #多線程使用方法,target為需要執行多線程的函數,args為函數中的參數,注意這里的參數寫成(i,),即如果只能一個參數,也要加上一個"," t.start() #開始執行多線程
程序運行結果如下:
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6$ python thread4.py
Hi, I am thread 0..lalala
Hi, I am thread 1..lalala
Hi, I am thread 2..lalala
Hi, I am thread 3..lalala
Hi, I am thread 4..lalala
Hi, I am thread 5..lalala
Hi, I am thread 6..lalala
Hi, I am thread 7..lalala
Hi, I am thread 8..lalala
Hi, I am thread 9..lalala
Hi, I am thread 10..lalala
Hi, I am thread 11..lalala
Hi, I am thread 12..lalala
Hi, I am thread 13..lalala
Hi, I am thread 14..lalala
Hi, I am thread 15..lalala
Hi, I am thread 16..lalala
Hi, I am thread 17..lalala
Hi, I am thread 18..lalala
Hi, I am thread 19..lalala
直接看執行結果是看不出什么的,這里說一下這個程序的執行過程:0到19是同時打印輸入的,在打印19后,程序sleep 1秒后才結束程序的運行。
上面這個程序有20個線程執行,每個線程都是:打印字符串+sleep(1)。我們實際看到的結果是0到19同時打印,然后才sleep 1秒,但是需要注意的是,并非是20個線程才執行一次sleep(1),而是在每個線程中都執行了一次sleep(1),即該程序實際上是執行了20次sleep(1),而我們實際看到的結果是程序運行時僅僅是暫停了1秒,那是因為這20次sleep(1)是并發執行的。
上面的程序可以這么去理解:20個線程相當于有20匹馬,20匹馬同時起跑(打印字符串),然后以同時停1秒(sleep(1)),最后同時到達終點(20個線程運行結束,即程序執行結束)。
為了更好的理解上面的程序,可以把上面的代碼改為如下:
import threading import time def run(num): print 'Hi, I am thread %s..lalala' % num time.sleep(1) for i in range(20): t = threading.Thread(target=run, args=(i,)) t.start() t.join() #等上一個線程執行完后再執行下一個線程
執行結果如下:
xpleaf@xpleaf-machine:/mnt/hgfs/Python/day6$ python thread4.py
Hi, I am thread 0..lalala
Hi, I am thread 1..lalala
Hi, I am thread 2..lalala
Hi, I am thread 3..lalala
Hi, I am thread 4..lalala
Hi, I am thread 5..lalala
Hi, I am thread 6..lalala
Hi, I am thread 7..lalala
Hi, I am thread 8..lalala
Hi, I am thread 9..lalala
Hi, I am thread 10..lalala
Hi, I am thread 11..lalala
Hi, I am thread 12..lalala
Hi, I am thread 13..lalala
Hi, I am thread 14..lalala
Hi, I am thread 15..lalala
Hi, I am thread 16..lalala
Hi, I am thread 17..lalala
Hi, I am thread 18..lalala
Hi, I am thread 19..lalala
執行結果看上去跟前面是一樣的,但執行過程卻是這樣的:每打印一次字符串,再暫停一秒。
通過這個程序,也就可以更好的理解Python的多線程并發執行了,當然,因為這是一個動態的過程,所以把程序執行一遍后會有更好的理解。
3.Python多線程使用方法2
程序代碼如下:
import threading,time class MyThread(threading.Thread): def __init__(self, num): threading.Thread.__init__(self) self.num = num def run(self): #this name must be 'run' print 'I am thread %s' % self.num time.sleep(2) for i in range(20): t = MyThread(i) t.start()
程序的執行結果與方法1是一樣的,這里就不給出了,只是這里利用了面向對象編程的思想方法來設計程序代碼。
更多關于Python相關內容感興趣的讀者可查看本站專題:《Python進程與線程操作技巧總結》、《Python數據結構與算法教程》、《Python函數使用技巧總結》、《Python字符串操作技巧匯總》、《Python入門與進階經典教程》、《Python+MySQL數據庫程序設計入門教程》及《Python常見數據庫操作技巧匯總》
希望本文所述對大家Python程序設計有所幫助。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。