[英]Using threading/multiprocessing in python to do multiple calculations at the same time
我有一個數字清單。 我想對列表中的每個數字執行一些耗時的操作,並使用所有結果創建一個新列表。 這是我所擁有的簡化版本:
def calcNum(n):#some arbitrary, time-consuming calculation on a number
m = n
for i in range(5000000):
m += i%25
if m > n*n:
m /= 2
return m
nums = [12,25,76,38,8,2,5]
finList = []
for i in nums:
return_val = calcNum(i)
finList.append(return_val)
print(finList)
現在,我想利用CPU中的多個內核,並給每個內核一個處理一個數字的任務,並且由於“數字計算”功能自始至終都是自包含的,所以我認為這是相當簡單,並且是多處理/線程的理想情況。
我的問題是,應該使用哪一個(多處理或線程處理?),最簡單的方法是什么?
我用在其他問題中發現的各種代碼進行了測試,以實現此目的,盡管它運行良好,但似乎並沒有進行任何實際的多線程/處理,並且所需的時間與我的第一個測試一樣長:
from multiprocessing.pool import ThreadPool
def calcNum(n):#some arbitrary, time-consuming calculation on a number
m = n
for i in range(5000000):
m += i%25
if m > n*n:
m /= 2
return m
pool = ThreadPool(processes=3)
nums = [12,25,76,38,8,2,5]
finList = []
for i in nums:
async_result = pool.apply_async(calcNum, (i,))
return_val = async_result.get()
finList.append(return_val)
print(finList)
multiprocessing.pool
和pool.map
是您最好的朋友。 它隱藏了所有其他復雜的隊列,使您省去了很多麻煩。 您所需要做的就是設置池,為其分配最大進程數,將其指向該函數並且可迭代。 請參閱下面的工作代碼。
由於該join
和用例pool.map
可以正常工作,因此該程序將等到所有進程都返回某些內容后再給出結果。
from multiprocessing.pool import Pool
def calcNum(n):#some arbitrary, time-consuming calculation on a number
print "Calcs Started on ", n
m = n
for i in range(5000000):
m += i%25
if m > n*n:
m /= 2
return m
if __name__ == "__main__":
p = Pool(processes=3)
nums = [12,25,76,38,8,2,5]
finList = []
result = p.map(calcNum, nums)
p.close()
p.join()
print result
那會給你這樣的東西:
Calcs Started on 12
Calcs Started on 25
Calcs Started on 76
Calcs Started on 38
Calcs Started on 8
Calcs Started on 2
Calcs Started on 5
[72, 562, 5123, 1270, 43, 23, 23]
無論何時啟動每個進程或何時完成,map都會等待每個進程完成,然后將它們全部以正確的順序放回去(對應於可迭代的輸入)。
正如@Guy所提到的,GIL在這里傷害了我們。 您可以在上面的代碼中將Pool
更改為ThreadPool
,並查看它如何影響計算時間。 由於使用了相同的函數,因此GIL僅允許一個線程一次使用calcNum
函數。 因此它足夠接近仍可以串行運行。 Multirocessing
與process
或pool
本質上開始你的腳本,它周圍的GIL的問題得到進一步的實例。 如果您在上述期間觀察正在運行的進程,則將在池運行時看到“ python.exe”的其他實例啟動。 在這種情況下,您會看到總數為4。
我想您會受到python Global Interpreter Lock的影響
GIL之所以引起爭議,是因為它在某些情況下阻止多線程CPython程序充分利用多處理器系統。
嘗試改用多處理
from multiprocessing import Pool
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.