簡體   English   中英

在python中使用線程化/多重處理來同時進行多個計算

[英]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.poolpool.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函數。 因此它足夠接近仍可以串行運行。 Multirocessingprocesspool本質上開始你的腳本,它周圍的GIL的問題得到進一步的實例。 如果您在上述期間觀察正在運行的進程,則將在池運行時看到“ python.exe”的其他實例啟動。 在這種情況下,您會看到總數為4。

我想您會受到python Global Interpreter Lock的影響

GIL之所以引起爭議,是因為它在某些情況下阻止多線程CPython程序充分利用多處理器系統。

嘗試改用多處理

from multiprocessing import Pool

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM