『壹』 python 下的多線程選哪個比較好
這主要看你的需求是什麼
如果主要是應對 IO負載 可以用 threading,線程間可共用內存,相當簡單方便
如果主要是應對 運算負載 就必須要用 multiprocessing 了
因為python自身不能充分利用多內核,所以需要用多個進程來充分利用cpu運算能力
但是用 multiprocessing ,進程間通信比起線程就麻煩得多了
『貳』 python多線程的幾種方法
Python進階(二十六)-多線程實現同步的四種方式
臨界資源即那些一次只能被一個線程訪問的資源,典型例子就是列印機,它一次只能被一個程序用來執行列印功能,因為不能多個線程同時操作,而訪問這部分資源的代碼通常稱之為臨界區。
鎖機制
threading的Lock類,用該類的acquire函數進行加鎖,用realease函數進行解鎖
import threadingimport timeclass Num:
def __init__(self):
self.num = 0
self.lock = threading.Lock() def add(self):
self.lock.acquire()#加鎖,鎖住相應的資源
self.num += 1
num = self.num
self.lock.release()#解鎖,離開該資源
return num
n = Num()class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item def run(self):
time.sleep(2)
value = n.add()#將num加1,並輸出原來的數據和+1之後的數據
print(self.item,value)for item in range(5):
t = jdThread(item)
t.start()
t.join()#使線程一個一個執行
當一個線程調用鎖的acquire()方法獲得鎖時,鎖就進入「locked」狀態。每次只有一個線程可以獲得鎖。如果此時另一個線程試圖獲得這個鎖,該線程就會變為「blocked」狀態,稱為「同步阻塞」(參見多線程的基本概念)。
直到擁有鎖的線程調用鎖的release()方法釋放鎖之後,鎖進入「unlocked」狀態。線程調度程序從處於同步阻塞狀態的線程中選擇一個來獲得鎖,並使得該線程進入運行(running)狀態。
信號量
信號量也提供acquire方法和release方法,每當調用acquire方法的時候,如果內部計數器大於0,則將其減1,如果內部計數器等於0,則會阻塞該線程,知道有線程調用了release方法將內部計數器更新到大於1位置。
import threadingimport timeclass Num:
def __init__(self):
self.num = 0
self.sem = threading.Semaphore(value = 3) #允許最多三個線程同時訪問資源
def add(self):
self.sem.acquire()#內部計數器減1
self.num += 1
num = self.num
self.sem.release()#內部計數器加1
return num
n = Num()class jdThread(threading.Thread):
def __init__(self,item):
threading.Thread.__init__(self)
self.item = item def run(self):
time.sleep(2)
value = n.add()
print(self.item,value)for item in range(100):
『叄』 現在三方包支持最好的python3是哪個版本
3.4
基本都是支持3.3+的,對3.2很多不支持了。
對於3.5,由於在windows上採用了vs2015編譯,運行時庫變化太大,mingw無法編譯對應的二進制擴展。所以很多二進制包對3.5支持比較差。
還有一個原因,3.4是最後一個支持WinXP的官方python3版本。
python35 變化較大,引入的很多新特性很多IDE並不支持
因此,由於Python的跨平台特性,因此兼容性最好的還是python3.4。Debian Jessie默認的Python 3就是這個版本。
『肆』 python3怎麼在一個class中使用多線程
import threading def fun1(func): func.start() #啟動線程2 for i in range(5): print 'x',i func.join() fun2() def fun2(): for i in range(60): print 'y',i tfunc2=threading.Thread(target=fun2) tfunc1=threading.Thread(target=fun1,arg...
『伍』 python3 創建線程時不用args傳參,執行線程時為什麼不是同時執行
在Python多線程下,每個線程的執行方式:
1、獲取GIL
2、執行代碼直到sleep或者是python虛擬機將其掛起。
3、釋放GIL
可見,某個線程想要執行,必須先拿到GIL,我們可以把GIL看作是「通行證」,並且在一個python進程中,GIL只有一個。拿不到通行證的線程,就不允許進入CPU執行。
在Python2.x里,GIL的釋放邏輯是當前線程遇見IO操作或者ticks計數達到100(ticks可以看作是Python自身的一個計數器,專門做用於GIL,每次釋放後歸零,這個計數可以通過
sys.setcheckinterval 來調整),進行釋放。
而每次釋放GIL鎖,線程進行鎖競爭、切換線程,會消耗資源。並且由於GIL鎖存在,python里一個進程永遠只能同時執行一個線程(拿到GIL的線程才能執行),這就是為什麼在多核CPU上,python的多線程效率並不高。
那麼是不是python的多線程就完全沒用了呢?
在這里我們進行分類討論:
1、CPU密集型代碼(各種循環處理、計數等等),在這種情況下,由於計算工作多,ticks計數很快就會達到閾值,然後觸發GIL的釋放與再競爭(多個線程來回切換當然是需要消耗資源的),所以python下的多線程對CPU密集型代碼並不友好。
2、IO密集型代碼(文件處理、網路爬蟲等),多線程能夠有效提升效率(單線程下有IO操作會進行IO等待,造成不必要的時間浪費,而開啟多線程能在線程A等待時,自動切換到線程B,可以不浪費CPU的資源,從而能提升程序執行效率)。所以python的多線程對IO密集型代碼比較友好。
而在python3.x中,GIL不使用ticks計數,改為使用計時器(執行時間達到閾值後,當前線程釋放GIL),這樣對CPU密集型程序更加友好,但依然沒有解決GIL導致的同一時間只能執行一個線程的問題,所以效率依然不盡如人意。
請注意:多核多線程比單核多線程更差,原因是單核下多線程,每次釋放GIL,喚醒的那個線程都能獲取到GIL鎖,所以能夠無縫執行,但多核下,CPU0釋放GIL後,其他CPU上的線程都會進行競爭,但GIL可能會馬上又被CPU0拿到,導致其他幾個CPU上被喚醒後的線程會醒著等待到切換時間後又進入待調度狀態,這樣會造成線程顛簸(thrashing),導致效率更低
回到最開始的問題:經常我們會聽到老手說:「python下想要充分利用多核CPU,就用多進程」,原因是什麼呢?
原因是:每個進程有各自獨立的GIL,互不幹擾,這樣就可以真正意義上的並行執行,所以在python中,多進程的執行效率優於多線程(僅僅針對多核CPU而言)。
所以在這里說結論:多核下,想做並行提升效率,比較通用的方法是使用多進程,能夠有效提高執行效率
『陸』 python 3.x 多線程 怎麼樣
python目前不適應運行在多核上的多線程。
僅能使用單核,如果需要多核你可以考慮多進程方式。
『柒』 python3 做一個多線程下載文件的程序 多線程問題
可以用is_active來判斷。
不過你可以預分配文件空間,直接寫,主要不沖突就行了。
『捌』 怎麼樣優雅的使用python多線程
python自帶的多線程比較麻煩,建議使用多進程哦
如果一定要多線程的話建議使用自帶的threading庫,不建議使用_thread庫
『玖』 python 怎麼實現多線程的
線程也就是輕量級的進程,多線程允許一次執行多個線程,Python是多線程語言,它有一個多線程包,GIL也就是全局解釋器鎖,以確保一次執行單個線程,一個線程保存GIL並在將其傳遞給下一個線程之前執行一些操作,也就產生了並行執行的錯覺。