前言
Python多進程適用的場景:計算密集型(CPU密集型)任務
Python多線程適用的場景:IO密集型任務
計算密集型任務一般指需要做大量的邏輯運算,比如上億次的加減乘除,使用多核CPU可以并發提高計算性能。
IO密集型任務一般指輸入輸出型,比如文件的讀取,或者網絡的請求,這類場景一般會遇到IO阻塞,使用多核CPU來執行并不會有太高的性能提升。
下面使用一臺64核的虛擬機來執行任務,通過示例代碼來區別它們,
示例1:執行計算密集型任務,進行1億次運算
使用多進程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
from multiprocessing import Process import os, time # 計算密集型任務 def work(): res = 0 for i in range ( 100 * 100 * 100 * 100 ): # 億次運算 res * = i if __name__ = = "__main__" : l = [] print ( "本機為" , os.cpu_count(), "核 CPU" ) # 本機為64核 start = time.time() for i in range ( 4 ): p = Process(target = work) # 多進程 l.append(p) p.start() for p in l: p.join() stop = time.time() print ( "計算密集型任務,多進程耗時 %s" % (stop - start)) |
使用多線程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
from threading import Thread import os, time # 計算密集型任務 def work(): res = 0 for i in range ( 100 * 100 * 100 * 100 ): # 億次運算 res * = i if __name__ = = "__main__" : l = [] print ( "本機為" , os.cpu_count(), "核 CPU" ) # 本機為64核 start = time.time() for i in range ( 4 ): p = Thread(target = work) # 多線程 l.append(p) p.start() for p in l: p.join() stop = time.time() print ( "計算密集型任務,多線程耗時 %s" % (stop - start)) |
兩段代碼輸出:
本機為 64 核 CPU
計算密集型任務,多進程耗時 6.864224672317505
本機為 64 核 CPU
計算密集型任務,多線程耗時 37.91042113304138
說明:上述代碼中,分別使用4個多進程和4個多線程去執行億次運算,多進程耗時6.86s,多線程耗時37.91s,可見在計算密集型任務場景,使用多進程能大大提高效率。
另外,當分別使用8個多進程和8個多線程去執行億次運算時,耗時差距更大,輸出如下:
本機為 64 核 CPU
計算密集型任務,多進程耗時 6.811635971069336
本機為 64 核 CPU
計算密集型任務,多線程耗時 113.53767895698547
可見在64核的cpu機器下,同時使用8個多進程和4個多進程效率幾乎一樣。而使用多線程則就效率較慢。要最高效地利用CPU,計算密集型任務同時進行的數量應當等于CPU的核心數
示例2:400次,阻塞兩秒,讀取文件
使用多進程(4核cpu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
from multiprocessing import Process import os, time # I/0密集型任務 def work(): time.sleep( 5 ) # 阻塞兩秒 if __name__ = = "__main__" : l = [] print ( "本機為" , os.cpu_count(), "核 CPU" ) start = time.time() for i in range ( 1000 ): p = Process(target = work) # 多進程 l.append(p) p.start() for p in l: p.join() stop = time.time() print ( "I/0密集型任務,多進程耗時 %s" % (stop - start)) |
使用多線程(4核cpu)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
from threading import Thread import os, time # I/0密集型任務 def work(): time.sleep( 5 ) # 阻塞兩秒 if __name__ = = "__main__" : l = [] print ( "本機為" , os.cpu_count(), "核 CPU" ) start = time.time() for i in range ( 1000 ): p = Thread(target = work) # 多線程 l.append(p) p.start() for p in l: p.join() stop = time.time() print ( "I/0密集型任務,多線程耗時 %s" % (stop - start)) |
輸出:
本機為 64 核 CPU
I/0密集型任務,多進程耗時 12.28218412399292
本機為 64 核 CPU
I/0密集型任務,多線程耗時 5.399136066436768
說明:python的多線程有于GIL鎖的存在,無論是多少核的cpu機器,也只能使用單核,從輸出結果來看,對于IO密集型任務使用多線程比較占優。
FAQ:執行多進程的io密集型任務時,報了一個錯:
OSError: [Errno 24] Too many open files
原因:linux系統限制
1
2
|
ulimit - n # 輸出 1024 |
解決:(臨時提高系統限制,重啟后失效)
1
|
ulimit - n 10240 |
總結
到此這篇關于Python多進程與多線程使用場景的文章就介紹到這了,更多相關Python多進程與使用場景內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/hhs_1996/article/details/114317308