使用Python實現(xiàn)多線程和多處理方法
在本教程中,我們將學(xué)習(xí)如何使用Python實現(xiàn)多線程和多處理方法。這些方法指導(dǎo)操作系統(tǒng)優(yōu)化使用系統(tǒng)硬件,從而提高代碼執(zhí)行效率。多線程引用Wiki的解釋—在計算機體系結(jié)構(gòu)中,多線程是指從軟件或者硬件上實現(xiàn)多個線程并發(fā)執(zhí)行的技術(shù)。具有多線程能力的計算機因有硬件支持而能夠在同一時間執(zhí)行多個線程,進而提升整體處理性能。并發(fā)指的是可以實現(xiàn)多個進程的并行執(zhí)行,從而實現(xiàn)更快的運行時間。當(dāng)執(zhí)行基于I/O的任務(wù)(如下載圖像和文件)時,多線程是更有效的,另一方面多處理也適合于基于CPU的計算密集型任務(wù)。Python中的多線程實現(xiàn)為了實現(xiàn)多線程,我們將使用Python的標(biāo)準(zhǔn)庫threading。默認情況下,該庫Python會默認安裝,因此可以直接在代碼中導(dǎo)入。為了演示多線程的有效性,我們將從Unsplash下載5幅圖像。讓我們觀察一下當(dāng)我們按順序下載這些圖像時的執(zhí)行時間:#### 導(dǎo)入請求庫import requests
#### 定義函數(shù)def down_img(name,link): data = requests.get(link).content name = f"/home/isud/DidYouKnow/Tutorial 5/{name}.jpg" with open(name, "wb") as file: file.write(data)
#### 連續(xù)下載5張圖片%%timeit -n1 -r1images = ['https://images.unsplash.com/photo-1531458999205-f31f14fa217b', 'https://images.unsplash.com/photo-1488572749058-7f52dd70e0fa', 'https://images.unsplash.com/photo-1531404610614-68f9e73e35db', 'https://images.unsplash.com/photo-1523489405193-3884f5ca475f', 'https://images.unsplash.com/photo-1565098735462-5db3412ac4cb']for i,link in enumerate(images): down_img(i,link)
#### %%timeit results51.4 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)可以觀察到,5張圖片的完整下載耗時51.4秒,而且只有在上一次下載結(jié)束后才開始新的下載。現(xiàn)在讓我們看看多線程如何提高代碼性能。#### 導(dǎo)入必要的庫import threadingimport requests
#### 定義函數(shù)def down_img(name,link): data = requests.get(link).content name = f"/home/isud/DidYouKnow/Tutorial 5/{name}.jpg" with open(name, "wb") as file: file.write(data)
#### 并行線程下載圖像%%timeit -n1 -r1threads = []images = ['https://images.unsplash.com/photo-1531458999205-f31f14fa217b', 'https://images.unsplash.com/photo-1488572749058-7f52dd70e0fa', 'https://images.unsplash.com/photo-1531404610614-68f9e73e35db', 'https://images.unsplash.com/photo-1523489405193-3884f5ca475f', 'https://images.unsplash.com/photo-1565098735462-5db3412ac4cb']for i,link in enumerate(images): t = threading.Thread(target=down_img, args=(i,link)) t.start() threads.a(chǎn)ppend(t)
for thread in threads: thread.join()
#### %%timeit results25.6 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)代碼解釋-定義圖像下載循環(huán):第1步(線程初始化)——Python在一個線程中運行完整的代碼(我們稱之為主線程)。在本例中,通過從線程庫調(diào)用Thread函數(shù),我們啟動并行線程并為它們分配一個要執(zhí)行的目標(biāo)進程(在本例中為down_image)。被調(diào)用函數(shù)所需的所有參數(shù)都應(yīng)作為序列對象(在本例中為元組)傳遞。對Thread函數(shù)的每次調(diào)用都會啟動一個新線程(我們稱之為并行線程)。第2步(線程啟動)——調(diào)用線程的start方法將指示Python啟動線程執(zhí)行。如果for循環(huán)在主線程中執(zhí)行,而函數(shù)調(diào)用在并行線程中,則for循環(huán)的執(zhí)行將在圖片下載過程中繼續(xù)執(zhí)行。步驟3(線程的join)——每個新線程都被捕獲到一個名為threads的列表中,然后通過調(diào)用join方法將并行線程連接到主線程。為什么需要使用join?在第2步之前,我們所有的線程(主線程和并行線程)都是并行執(zhí)行的,在這種情況下,主線程完成任務(wù)的時間可以比并行線程完成任務(wù)早很多,及主線程會結(jié)束更早。為了避免這種情況,將并行線程連接到主線程是必須的,這將確保只有在并行線程完成之后才完成主線程的執(zhí)行。下圖說明了這兩種情況:
可以看出,下載圖像的執(zhí)行時間減少了近50%(大約25.6秒)。上面的示例展示了多線程在I/O操作中的幫助,以及如何提高下載/上傳過程的效率。多處理與在單個進程中執(zhí)行多個線程的多線程不同,多處理為每個任務(wù)啟動一個新的并行進程。如前所述,它為CPU密集型任務(wù)(需要大量計算的任務(wù))提供了相當(dāng)大的運行時改進。在Python中實現(xiàn)多處理multiprocessing是另一個在Python中支持多處理特性的標(biāo)準(zhǔn)庫,為了理解它的功能,我們將多次調(diào)用一個計算密集型函數(shù),來計算從1到1千萬的數(shù)字的平方。此函數(shù)并行執(zhí)行8次,讓我們觀察一下這個函數(shù)在正常情況下的性能。#### 導(dǎo)入時間庫import time
#### 定義函數(shù)def demo_func(num): for i in range(num): a = i**2
#### 順序調(diào)用演示函數(shù)%%timeit -n1 -r1for i in range(8): demo_func(10000000)
#### %%timeit 結(jié)果21.2 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)演示函數(shù)的順序執(zhí)行總共花費了21.2秒,現(xiàn)在讓我們檢查在多處理設(shè)置中執(zhí)行此操作時的性能提升。#### 導(dǎo)入庫import time
#### 定義函數(shù)def demo_func(num): for i in range(num): a = i**2
#### 多處理demo函數(shù)%%timeit -n1 -r1processes = []lop_size = [10000000,10000000,10000000,10000000,10000000,10000000,10000000, 10000000]p = multiprocessing.Pool()p.map(demo_func,lop_size)p.close()p.join()
#### %%timeit 結(jié)果11.6 s ± 0 ns per loop (mean ± std. dev. of 1 run, 1 loop each)在多處理框架下,執(zhí)行時間減少了50%,達到11.6秒。在順序處理中,一次使用一個CPU內(nèi)核,而在多個處理中,所有系統(tǒng)內(nèi)核都是并行使用的。CPU使用率屏幕截圖顯示了相同的情況:
上圖中的每一行代表一個CPU核。請注意,在順序執(zhí)行中,每個函數(shù)調(diào)用都會觸發(fā)一個核,而在并行執(zhí)行中,所有核都是同時觸發(fā)的。代碼說明步驟1(池創(chuàng)建)-池方法創(chuàng)建可并行利用的進程池。在沒有任何參數(shù)的情況下,創(chuàng)建的進程數(shù)等于系統(tǒng)上的CPU核數(shù)。我有一個四核系統(tǒng),這意味著,在執(zhí)行時的8個函數(shù)調(diào)用中,前4個調(diào)用將并行運行,然后是下4個函數(shù)調(diào)用。請注意,你還可以在池中定義一個自定義的進程數(shù)(多于內(nèi)核數(shù)),但超過某個值時,它將開始占用系統(tǒng)內(nèi)存并可能降低性能步驟2(池映射)-這是指示進程執(zhí)行特定函數(shù)(第一個參數(shù))以及要傳遞給它的參數(shù)列表(第二個參數(shù))步驟3(Pool Close)-Close方法指示Python解釋器,我們已經(jīng)提交了要提交給池的所有內(nèi)容,將來不再向池提供更多的輸入。步驟4(池連接)-與線程的情況一樣,Join方法確保代碼執(zhí)行只在所有并行進程完成后完成。從上面的場景中,我們可以看到多處理是如何在高效的代碼性能方面成為一個很好的幫手。結(jié)束本教程中,我們將重點放在通過優(yōu)化系統(tǒng)硬件來提高代碼性能上。希望這篇教程能幫助你,你能學(xué)到一些新東西。
請輸入評論內(nèi)容...
請輸入評論/評論長度6~500個字
最新活動更多
-
即日-10.29立即報名>> 2024德州儀器嵌入式技術(shù)創(chuàng)新發(fā)展研討會
-
10月31日立即下載>> 【限時免費下載】TE暖通空調(diào)系統(tǒng)高效可靠的組件解決方案
-
即日-11.13立即報名>>> 【在線會議】多物理場仿真助跑新能源汽車
-
11月14日立即報名>> 2024工程師系列—工業(yè)電子技術(shù)在線會議
-
12月19日立即報名>> 【線下會議】OFweek 2024(第九屆)物聯(lián)網(wǎng)產(chǎn)業(yè)大會
-
即日-12.26火熱報名中>> OFweek2024中國智造CIO在線峰會
推薦專題
- 1 Intel宣布40年來最重大轉(zhuǎn)型:年底前裁員15000人、拋掉2/3房產(chǎn)
- 2 因美封殺TikTok,字節(jié)股價骨折!估值僅Meta1/5
- 3 宏山激光重磅發(fā)布行業(yè)解決方案,助力智能制造產(chǎn)業(yè)新飛躍
- 4 國產(chǎn)AI芯片公司破產(chǎn)!白菜價拍賣
- 5 具身智能火了,但規(guī)模落地還需時間
- 6 國產(chǎn)英偉達們,抓緊沖刺A股
- 7 三次錯失風(fēng)口!OpenAI前員工殺回AI編程賽道,老東家捧金相助
- 8 英特爾賦能智慧醫(yī)療,共創(chuàng)數(shù)字化未來
- 9 英偉達的麻煩在后頭?
- 10 將“網(wǎng)紅”變成“商品”,AI“爆改”實力拉滿
- 高級軟件工程師 廣東省/深圳市
- 自動化高級工程師 廣東省/深圳市
- 光器件研發(fā)工程師 福建省/福州市
- 銷售總監(jiān)(光器件) 北京市/海淀區(qū)
- 激光器高級銷售經(jīng)理 上海市/虹口區(qū)
- 光器件物理工程師 北京市/海淀區(qū)
- 激光研發(fā)工程師 北京市/昌平區(qū)
- 技術(shù)專家 廣東省/江門市
- 封裝工程師 北京市/海淀區(qū)
- 結(jié)構(gòu)工程師 廣東省/深圳市