導航:首頁 > 編程語言 > python多線程的問題

python多線程的問題

發布時間:2022-11-27 13:18:52

『壹』 為什麼有人說 python 的多線程是雞肋呢

首先,我並不認同這個觀點,我覺得覺得Python 的多線程是雞肋多餘的人,應該還沒有完全使用過Python 的多線程功能,並沒有發掘它的潛在能力。

Python多線程最大的優點就是使用方便,很多時候我們並不需要做大量的密集型數據的處理運算,這時候用Python多線程是最方便快捷的,可以大大減少工作量、提高工作效率。

從以上幾點我們就可以看出,Python多線程並不雞肋,只是有時候使用者在不巧當的地方使用,它自然不是那麼順手,我們加深熟悉了解Python多線程的適用范圍。

『貳』 Python多線程是什麼意思

幾乎所有的操作系統都支持同時運行多個任務,一個任務通常就是一個程序,所有運行中的任務都對應一個進程。即當一個程序進入內存運行時,即變成一個進程。進程就是處於運行過程中的程序,並且具有一定的獨立功能。進程是系統進行資源分配調度的一個獨立單位,當一個程序運行時,內部可能包含多個順序執流,每個順序執行流就是一個線程。
1、線程在程序中是獨立的,並發的執行流,劃分尺度小於進程,所有多線程程序的並發性高;
2、進程在執行過程中擁有獨立的內存單元,而多個線程共享內存,可以極大地提高進程程序的運行效率;
3、線程比進程具有更高的性能,由於同一個進程中的線程都有共性,多個線程共享同一個進程的虛擬空間,可以很容易實現通信。操作系統在創建進程中,必須為該進程分配獨立內存空間,分配大量相關資源,但創建線程則簡單得多。

『叄』 Python多線程總結

在實際處理數據時,因系統內存有限,我們不可能一次把所有數據都導出進行操作,所以需要批量導出依次操作。為了加快運行,我們會採用多線程的方法進行數據處理, 以下為我總結的多線程批量處理數據的模板:

主要分為三大部分:


共分4部分對多線程的內容進行總結。

先為大家介紹線程的相關概念:

在飛車程序中,如果沒有多線程,我們就不能一邊聽歌一邊玩飛車,聽歌與玩 游戲 不能並行;在使用多線程後,我們就可以在玩 游戲 的同時聽背景音樂。在這個例子中啟動飛車程序就是一個進程,玩 游戲 和聽音樂是兩個線程。

Python 提供了 threading 模塊來實現多線程:

因為新建線程系統需要分配資源、終止線程系統需要回收資源,所以如果可以重用線程,則可以減去新建/終止的開銷以提升性能。同時,使用線程池的語法比自己新建線程執行線程更加簡潔。

Python 為我們提供了 ThreadPoolExecutor 來實現線程池,此線程池默認子線程守護。它的適應場景為突發性大量請求或需要大量線程完成任務,但實際任務處理時間較短。

其中 max_workers 為線程池中的線程個數,常用的遍歷方法有 map 和 submit+as_completed 。根據業務場景的不同,若我們需要輸出結果按遍歷順序返回,我們就用 map 方法,若想誰先完成就返回誰,我們就用 submit+as_complete 方法。

我們把一個時間段內只允許一個線程使用的資源稱為臨界資源,對臨界資源的訪問,必須互斥的進行。互斥,也稱間接制約關系。線程互斥指當一個線程訪問某臨界資源時,另一個想要訪問該臨界資源的線程必須等待。當前訪問臨界資源的線程訪問結束,釋放該資源之後,另一個線程才能去訪問臨界資源。鎖的功能就是實現線程互斥。

我把線程互斥比作廁所包間上大號的過程,因為包間里只有一個坑,所以只允許一個人進行大號。當第一個人要上廁所時,會將門上上鎖,這時如果第二個人也想大號,那就必須等第一個人上完,將鎖解開後才能進行,在這期間第二個人就只能在門外等著。這個過程與代碼中使用鎖的原理如出一轍,這里的坑就是臨界資源。 Python 的 threading 模塊引入了鎖。 threading 模塊提供了 Lock 類,它有如下方法加鎖和釋放鎖:

我們會發現這個程序只會列印「第一道鎖」,而且程序既沒有終止,也沒有繼續運行。這是因為 Lock 鎖在同一線程內第一次加鎖之後還沒有釋放時,就進行了第二次 acquire 請求,導致無法執行 release ,所以鎖永遠無法釋放,這就是死鎖。如果我們使用 RLock 就能正常運行,不會發生死鎖的狀態。

在主線程中定義 Lock 鎖,然後上鎖,再創建一個子 線程t 運行 main 函數釋放鎖,結果正常輸出,說明主線程上的鎖,可由子線程解鎖。

如果把上面的鎖改為 RLock 則報錯。在實際中設計程序時,我們會將每個功能分別封裝成一個函數,每個函數中都可能會有臨界區域,所以就需要用到 RLock 。

一句話總結就是 Lock 不能套娃, RLock 可以套娃; Lock 可以由其他線程中的鎖進行操作, RLock 只能由本線程進行操作。

『肆』 為什麼有人說 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是多線程語言,它有一個多線程包,GIL也就是全局解釋器鎖,以確保一次執行單個線程,一個線程保存GIL並在將其傳遞給下一個線程之前執行一些操作,也就產生了並行執行的錯覺。

『陸』 python多線程問題

a、b線程的執行順序是由系統進行調度決定的。這種調度有很強的隨機性。因此a、b線程誰先結束、誰後結束都是未知的。你可以運行以下程序,從而進一步的觀察其中a、b線程的執行情況。

後結束的線程必然是20000。因為最終次數會達到20000。而另一個必然是一個小於等於19999的數。相差次數是系統調度決定,是隨機的。並不存在「循環次數越大,相差就越大」的情況。你可以多試驗幾次試試。


importthreading
TOTAL=0
defmain():
MY_LOCK=threading.Lock()
classCountThread(threading.Thread):
def__init__(self,threadname):
threading.Thread.__init__(self)
self.threadname=threadname


defrun(self):
globalTOTAL
foriinrange(100):
MY_LOCK.acquire()
TOTAL=TOTAL+1
MY_LOCK.release()
print('%s:%s '%(self.threadname,TOTAL))
a=CountThread("a")
b=CountThread("b")
a.start()
b.start()

『柒』 python 線程過多怎麼處理

一般來說,多線程模式下,建議主線程只處理線程本身的調度,不去處理具體業務。通常在創建線程後,join等待所有線程退出。 就題主的問題,可以創建線程一、二之後,主線程等待線程一退出,之後用sys.exit退出。

『捌』 關於python多線程的一些問題。

  1. 創建的子線程默認是非守護的。

  2. 非守護:當主線程結束時,子線程繼續運行,二者互不影響。

  3. 子線程是守護線程:當主線程結束時,子線程也結束(不管子線程工作有沒有完成)。

  4. join作用是線程同步,是讓主線程等待子線程結束才結束(主線程完成工作了也不結束,阻塞等待,等子線程完成其工作才一起結束)。

相信此時你已經懂你的兩個問題了。

  1. 沒加join的時候主線程結束了,所以命令提示符>>>就出來了,可是子線程還沒結束,過了3/5秒後列印了字元串。加了join後主線程等兩個子線程都結束才一起結束,所以最後才出來>>>。

  2. 理解確實有點偏差。守護是指子線程守護著主線程,你死我也死,謂之守護。

『玖』 有關python多線程的問題

Python的多線程只能解決非IO密集型問題,屬於偽多線程,只能考慮多進程

『拾』 Python多線程的一些問題

python提供了兩個模塊來實現多線程thread 和threading ,thread 有一些缺點,在threading 得到了彌補,為了不浪費你和時間,所以我們直接學習threading 就可以了。
繼續對上面的例子進行改造,引入threadring來同時播放音樂和視頻:
#coding=utf-8import threadingfrom time import ctime,sleepdef music(func): for i in range(2): print "I was listening to %s. %s" %(func,ctime())
sleep(1)def move(func): for i in range(2): print "I was at the %s! %s" %(func,ctime())
sleep(5)

threads = []
t1 = threading.Thread(target=music,args=(u'愛情買賣',))
threads.append(t1)
t2 = threading.Thread(target=move,args=(u'阿凡達',))
threads.append(t2)if __name__ == '__main__': for t in threads:
t.setDaemon(True)
t.start() print "all over %s" %ctime()

import threading
首先導入threading 模塊,這是使用多線程的前提。

threads = []
t1 = threading.Thread(target=music,args=(u'愛情買賣',))
threads.append(t1)
創建了threads數組,創建線程t1,使用threading.Thread()方法,在這個方法中調用music方法target=music,args方法對music進行傳參。 把創建好的線程t1裝到threads數組中。
接著以同樣的方式創建線程t2,並把t2也裝到threads數組。

for t in threads:
t.setDaemon(True)
t.start()
最後通過for循環遍歷數組。(數組被裝載了t1和t2兩個線程)

setDaemon()
setDaemon(True)將線程聲明為守護線程,必須在start() 方法調用之前設置,如果不設置為守護線程程序會被無限掛起。子線程啟動後,父線程也繼續執行下去,當父線程執行完最後一條語句print "all over %s" %ctime()後,沒有等待子線程,直接就退出了,同時子線程也一同結束。

start()
開始線程活動。

運行結果:
>>> ========================= RESTART ================================
>>> I was listening to 愛情買賣. Thu Apr 17 12:51:45 2014 I was at the 阿凡達! Thu Apr 17 12:51:45 2014 all over Thu Apr 17 12:51:45 2014

從執行結果來看,子線程(muisc 、move )和主線程(print "all over %s" %ctime())都是同一時間啟動,但由於主線程執行完結束,所以導致子線程也終止。

繼續調整程序:
...if __name__ == '__main__': for t in threads:
t.setDaemon(True)
t.start()

t.join() print "all over %s" %ctime()

我們只對上面的程序加了個join()方法,用於等待線程終止。join()的作用是,在子線程完成運行之前,這個子線程的父線程將一直被阻塞。
注意: join()方法的位置是在for循環外的,也就是說必須等待for循環里的兩個進程都結束後,才去執行主進程。
運行結果:
>>> ========================= RESTART ================================
>>> I was listening to 愛情買賣. Thu Apr 17 13:04:11 2014 I was at the 阿凡達! Thu Apr 17 13:04:11 2014I was listening to 愛情買賣. Thu Apr 17 13:04:12 2014I was at the 阿凡達! Thu Apr 17 13:04:16 2014all over Thu Apr 17 13:04:21 2014

從執行結果可看到,music 和move 是同時啟動的。
開始時間4分11秒,直到調用主進程為4分22秒,總耗時為10秒。從單線程時減少了2秒,我們可以把music的sleep()的時間調整為4秒。
...def music(func): for i in range(2): print "I was listening to %s. %s" %(func,ctime())
sleep(4)
...

子線程啟動11分27秒,主線程運行11分37秒。
雖然music每首歌曲從1秒延長到了4 ,但通多程線的方式運行腳本,總的時間沒變化。

閱讀全文

與python多線程的問題相關的資料

熱點內容
php如何導入excel文件 瀏覽:237
同撈同煲哪個app可以看 瀏覽:861
微信查卷優惠券源碼 瀏覽:480
伺服器光碟機線怎麼插 瀏覽:12
新生兒下載哪個app好 瀏覽:487
摩托車壓縮比96 瀏覽:410
linux查看mysql內存 瀏覽:242
福建ca認證伺服器地址 瀏覽:567
三星安全文件夾怎麼取消應用程序 瀏覽:169
偶像來了哪個app能看 瀏覽:252
破解分銷源碼 瀏覽:184
androidudp服務端 瀏覽:771
電腦伺服器和內存有什麼區別 瀏覽:308
下載海爾哪個app可以查詢信息 瀏覽:385
暴風文件夾怎麼刪除 瀏覽:163
我的世界緩存文件在哪個文件夾 瀏覽:359
簡歷發壓縮包還是文件夾 瀏覽:85
mes系統用什麼伺服器5885v5 瀏覽:486
郵件伺服器可以怎麼查詢 瀏覽:727
啟動linux的sftp 瀏覽:66