python中的多線程
① python多線程是什麼意思
簡單地說就是作為可能是僅有的支持多線程的解釋型語言(perl的多線程是殘疾,PHP沒有多線程),Python的多線程是有compromise的,在任意時間只有一個Python解釋器在解釋Python bytecode。
UPDATE:如評論指出,Ruby也是有thread支持的,而且至少Ruby MRI是有GIL的。
如果你的代碼是CPU密集型,多個線程的代碼很有可能是線性執行的。所以這種情況下多線程是雞肋,效率可能還不如單線程因為有context switch
但是:如果你的代碼是IO密集型,多線程可以明顯提高效率。例如製作爬蟲(我就不明白為什麼Python總和爬蟲聯系在一起…不過也只想起來這個例子…),絕大多數時間爬蟲是在等待socket返回數據。這個時候C代碼里是有release GIL的,最終結果是某個線程等待IO的時候其他線程可以繼續執行。
反過來講:你就不應該用Python寫CPU密集型的代碼…效率擺在那裡…
如果確實需要在CPU密集型的代碼里用concurrent,就去用multiprocessing庫。這個庫是基於multi process實現了類multi thread的API介面,並且用pickle部分地實現了變數共享。
再加一條,如果你不知道你的代碼到底算CPU密集型還是IO密集型,教你個方法:
multiprocessing這個mole有一個mmy的sub mole,它是基於multithread實現了multiprocessing的API。
假設你使用的是multiprocessing的Pool,是使用多進程實現了concurrency
from multiprocessing import Pool
如果把這個代碼改成下面這樣,就變成多線程實現concurrency
from multiprocessing.mmy import Pool
兩種方式都跑一下,哪個速度快用哪個就行了。
UPDATE:
剛剛才發現concurrent.futures這個東西,包含ThreadPoolExecutor和ProcessPoolExecutor,可能比multiprocessing更簡單
② python多線程作用
總結起來,使用多線程編程具有如下幾個優點:
進程之間不能共享內存,但線程之間共享內存非常容易。
操作系統在創建進程時,需要為該進程重新分配系統資源,但創建線程的代價則小得多。因此,使用多線程來實現多任務並發執行比使用多進程的效率高。
Python 語言內置了多線程功能支持,而不是單純地作為底層操作系統的調度方式,從而簡化了 Python 的多線程編程。
在實際應用中,多線程是非常有用的。比如一個瀏覽器必須能同時下載多張圖片;一個 Web 伺服器必須能同時響應多個用戶請求;圖形用戶界面(GUI)應用也需要啟動單獨的線程,從主機環境中收集用戶界面事件……總之,多線程在實際編程中的應用是非常廣泛的。
③ python中多進程和多線程的區別
什麼是線程、進程?
進程(process)與線程(thread)是操作系統的基本概念,它們比較抽象,不容易掌握。
關於這兩者,最經典的一句話就是「進程是資源分配的最小單位,線程是CPU調度的最小單位」,線程是程序中一個單一的順序控制流程,進程內一個相對獨立的、可調度的執行單元,是系統獨立調度和分配CPU的基本單位指運行中的程序的調度單位,在單個程序中同時運行多個線程完成不同的工作,稱為多線程。
進程與線程的區別是什麼?
進程是資源分配的基本單位,所有與該進程有關的資源,都被記錄在進程式控制制塊PCB中,以表示該進程擁有這些資源或正在使用它們,另外,進程也是搶占處理機的調度單位,它擁有一個完整的虛擬地址空間,當進程發生調度時,不同的進程擁有不同的虛擬地址空間,而同一進程內的不同線程共享同一地址空間。
與進程相對應的,線程與資源分配無關,它屬於某一個進程,並與進程內的其他線程一起共享進程的資源,線程只由相關堆棧(系統棧或用戶棧)寄存器和線程式控制製表TCB組成,寄存器可被用來存儲線程內的局部變數,但不能存儲其他線程的相關變數。
通常在一個進程中可以包含若干個線程,它們可以利用進程所擁有的資源,在引入線程的操作系統中,通常都是把進程作為分配資源的基本單位,而把線程作為獨立運行和獨立調度的基本單位。
由於線程比進程更小,基本上不擁有系統資源,所以對它的調度所付出的開銷就會小得多,能更高效的提高系統內多個程序間並發執行的程度,從而顯著提高系統資源的利用率和吞吐量。
因而近年來推出的通用操作系統都引入了線程,以便進一步提高系統的並發性,並把它視為現代操作系統的一個重要指標。
④ 為什麼有人說 Python 的多線程是雞肋
因為 Python 中臭名昭著的 GIL。
那麼 GIL 是什麼?為什麼會有 GIL?多線程真的是雞肋嗎? GIL 可以去掉嗎?帶著這些問題,我們一起往下看,同時需要你有一點點耐心。
多線程是不是雞肋,我們先做個實驗,實驗非常簡單,就是將數字 「1億」 遞減,減到 0 程序就終止,這個任務如果我們使用單線程來執行,完成時間會是多少?使用多線程又會是多少?show me the code
那麼把 GIL 去掉可行嗎?
還真有人這么干多,但是結果令人失望,在1999年Greg Stein 和Mark Hammond 兩位哥們就創建了一個去掉 GIL 的 Python 分支,在所有可變數據結構上把 GIL 替換為更為細粒度的鎖。然而,做過了基準測試之後,去掉GIL的 Python 在單線程條件下執行效率將近慢了2倍。
Python之父表示:基於以上的考慮,去掉GIL沒有太大的價值而不必花太多精力。
⑤ 如何理解python的多線程編程
線程是程序員必須掌握的知識,多線程對於代碼的並發執行、提升代碼效率和運行都至關重要。今天就分享一個黑馬程序員Python多線程編程的教程,從0開始學習python多任務編程,想了解python高並發實現,從基礎到實踐,通過知識點 + 案例教學法幫助你想你想迅速掌握python多任務。
課程內容:
1.掌握多任務實現的並行和並發
2.掌握多進程實現多任務
3.掌握多線程實現多任務
4.掌握合理搭配多進程和線程
適用人群:
1、對python多任務編程感興趣的在校生及應屆畢業生。
2、對目前職業有進一步提升要求,希望從事python人工智慧行業高薪工作的在職人員。
3、對python人工智慧行業感興趣的相關人員。
基礎課程主講內容包括:
1.python多任務編程
基礎班課程大綱:
00-課程介紹
01-多任務介紹
02-進程介紹
03-使用多進程來完成多任務
04-多進程執行帶有參數的任務
05-獲取進程的編號
06-進程注意點
07-案例-多進程實現傳智視頻文件夾多任務拷貝器
08-線程介紹
09-使用多線程執行多任務
10-線程執行帶有參數的任務
11-主線程和子線程的結束順序
12-線程之間的執行順序是無序
13-線程和進程的對比
14-案例-多線程實現傳智視頻文件夾多任務拷貝器
15-課程總結
⑥ python 怎麼實現多線程的
線程也就是輕量級的進程,多線程允許一次執行多個線程,Python是多線程語言,它有一個多線程包,GIL也就是全局解釋器鎖,以確保一次執行單個線程,一個線程保存GIL並在將其傳遞給下一個線程之前執行一些操作,也就產生了並行執行的錯覺。
⑦ 請教python如何開啟多線程
可以定義函數把這些代碼放在不同的函數里,然後threading模塊
import threading
th1 = threading.Thread(target=func1, args=(arg1, arg2, ...))
照這樣再定義別的線程,開啟用Thread類的start方法
th1.start(); th2.start(); ...
⑧ Python多線程問題,怎麼解決
在python里線程出問題,可能會導致主進程崩潰。 雖然python里的線程是操作系統的真實線程。
那麼怎麼解決呢?通過我們用進程方式。子進程崩潰後,會完全的釋放所有的內存和錯誤狀態。所以進程更安全。 另外通過進程,python可以很好的繞過GIL,這個全局鎖問題。
但是進程也是有局限的。不要建立超過CPU總核數的進程,否則效率也不高。
簡單的總結一下。
當我們想實現多任務處理時,首先要想到使用multiprocessing, 但是如果覺著進程太笨重,那麼就要考慮使用線程。 如果多任務處理中需要處理的太多了,可以考慮多進程,每個進程再採用多線程。如果還處理不要,就要使用輪詢模式,比如使用poll event, twisted等方式。如果是GUI方式,則要通過事件機制,或者是消息機制處理,GUI使用單線程。
所以在python里線程不要盲目用, 也不要濫用。 但是線程不安全是事實。如果僅僅是做幾個後台任務,則可以考慮使用守護線程做。如果需要做一些危險操作,可能會崩潰的,就用子進程去做。 如果需要高度穩定性,同時並發數又不高的服務。則強烈建議用多進程的multiprocessing模塊實現。
在linux或者是unix里,進程的使用代價沒有windows高。還是可以接受的。
⑨ 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):
⑩ python多線程有什麼作用
線程在程序中是獨立的、並發的執行流。與分隔的進程相比,進程中線程之間的隔離程度要小,它們共享內存、文件句柄和其他進程應有的狀態。
因為線程的劃分尺度小於進程,使得多線程程序的並發性高。進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,從而極大地提高了程序的運行效率。
線程比進程具有更高的性能,這是由於同一個進程中的線程都有共性多個線程共享同一個進程的虛擬空間。線程共享的環境包括進程代碼段、進程的公有數據等,利用這些共享的數據,線程之間很容易實現通信。
操作系統在創建進程時,必須為該進程分配獨立的內存空間,並分配大量的相關資源,但創建線程則簡單得多。因此,使用多線程來實現並發比使用多進程的性能要高得多。
總結起來,使用多線程編程具有如下幾個優點:
進程之間不能共享內存,但線程之間共享內存非常容易。
操作系統在創建進程時,需要為該進程重新分配系統資源,但創建線程的代價則小得多。因此,使用多線程來實現多任務並發執行比使用多進程的效率高。
Python語言內置了多線程功能支持,而不是單純地作為底層操作系統的調度方式,從而簡化了 Python 的多線程編程。
在實際應用中,多線程是非常有用的。比如一個瀏覽器必須能同時下載多張圖片;一個 Web 伺服器必須能同時響應多個用戶請求;圖形用戶界面(GUI)應用也需要啟動單獨的線程,從主機環境中收集用戶界面事件……總之,多線程在實際編程中的應用是非常廣泛的。