簡體   English   中英

Python 多處理卡住

[英]Python multiprocessing gets stuck

我對 Python 和多處理完全陌生,我在網上找到了一些教程來幫助我理解多處理 package。

我的代碼有一組使用 RungeKutta4 方法的微分方程,我需要在不同的起始條件下運行大量計算。

代碼本身可以工作,但如果沒有多重處理,它需要很長時間才能完成,我認為使用並行化可能是理想的,因為計算是獨立的......

我正在使用 Anaconda 作為 IDE 順便說一句..

所以我用

import multiprocessing as mp
iterations = np.arange(start,end,step)
pool = mp.Pool(mp.cpu_count())                           # Step 1: Init multiprocessing.Pool()
results = pool.map(rungeKutta4, [k for k in iterations]) # Step 2: apply pool map              
pool.close()                                             # Step 3: close

當我在 Anaconda 中運行它時,我沒有收到錯誤,它開始計算但它永遠不會停止......我在哪里 go 錯了?

提前感謝您的幫助...

最好的

編輯:我在這里添加了整個代碼......

# Python program to implement Runge Kutta method 
# Markus Schmid
# 2020 Appalachian State University
# jupyter nbconvert --to python FILENAME.ipynb

# y" + 2*beta*y' + w0*sin(y) = A + B*cos(w*t)
# Import used libraries
import numpy as np
import math
import matplotlib.pyplot as plt
import time
from matplotlib import rc
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
rc('text', usetex=True)
import multiprocessing as mp
print("Number of processors: ", mp.cpu_count())
# list for time (x axis) and result (y axis)
result = []
w0 = 10                  # undamped angular frequency of the oscillator
beta = 1
B = 1
A = 0
B = 10
w = 4
theta_init = 0
theta_end = 20
theta_step = 0.1

# initial conditions
t0 = 0
y0 = 0
z0 = 0
t_final = 20                   # final time
h = 0.01                    # fixed step size
n = (int)((t_final - t0)/h)   # datapoints per RK4 iteration

# define functions
def funcf(t, y, z): 
    return (z)
def funcg(t, y, z): 
    return (A+B*math.cos(w*t) - 2*beta*z - w0*math.sin(y))

# Finds value of y for a given x using step size h 
# and initial value y0 at x0. 
def rungeKutta4(y): 
    # Count number of iterations using step size or 
    # step height h 
    t = t0
    z = z0
    n = (int)((t_final - t)/h)  
    for i in range(1, n + 1): 
        # Apply Runge Kutta to find next value of y
        k1 = h * funcf(t, y, z) 
        l1 = h * funcg(t, y, z)  

        k2 = h * funcf(t + 0.5 * h, y + 0.5 * k1, z + 0.5 * l1) 
        l2 = h * funcg(t + 0.5 * h, y + 0.5 * k1, z + 0.5 * l1)  

        k3 = h * funcf(t + 0.5 * h, y + 0.5 * k2, z + 0.5 * l2) 
        l3 = h * funcg(t + 0.5 * h, y + 0.5 * k2, z + 0.5 * l2) 

        k4 = h * funcf(t + h, y + k3, z + l3) 
        l4 = h * funcg(t + h, y + k3, z + l3) 

        # Update next value of y 
        y = y + (1.0 / 6.0)*(k1 + 2 * k2 + 2 * k3 + k4) 
        z = z + (1.0 / 6.0)*(l1 + 2 * l2 + 2 * l3 + l4) 

        #result.append(y)                
        t = t + h # Update next value of t
    return y 

iterations = np.arange(theta_init,theta_end+theta_step,theta_step)   # number iterations for omega sweep

start_time = time.time()
#for k in iterations:     # for serial calculation
#            rungeKutta4(k)
pool = mp.Pool(mp.cpu_count()) # Step 1: Init multiprocessing.Pool()
results = pool.map(rungeKutta4, [k for k in iterations]) # Step 2: apply pool map        
end_time = time.time()            
pool.close()  # Step 3: close
print ("The program took", end_time - start_time, "s to run")

#table = np.array(result).reshape(len(iterations),n)   # rearrange array, 1 row is const. theta0
timer = np.arange(t0,t_final,h) # time array

您的代碼看起來不錯,它適用於我(Ipython 和 python3.6.9),我在下面附上了結果和配置。

您是否嘗試在不同的python 虛擬環境(Anaconda 之外)中運行它? 如前所述(在 Ronald 的評論中), 其他 IDE存在 python 的多處理錯誤,請嘗試使用命令行/Ipython 運行它。 我以前甚至在vscode中也遇到過

配置:

蟒蛇配置

結果:

腳本結果

我最初的評論:

IDE 可以以意想不到的方式與 Python 交互。 在 stackoverflow 上的 IDE 中多次提到多處理行為不端。 因此,最好通過從 shell(ms-windows 上的 cmd.exe)直接調用 Python 來測試您的腳本。

你回復:

RuntimeError:在當前進程完成其引導階段之前,已嘗試啟動新進程。

為了使multiprocessing在 ms-windows 上正常工作,您必須能夠在腳本中導入代碼而不會產生副作用,例如啟動新進程

這意味着您必須將除了導入和函數/類定義之外的所有內容都放在一個主塊中,就像這個受文檔啟發的示例一樣:

from multiprocessing import Process

def foo():
    print('hello')

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()

基本上,ms-windows 缺少類 UNIX 系統上存在的漂亮的fork()系統調用。 因此,Python 開發人員必須想出一個巧妙的技巧來讓multiprocessing處理在 ms-windows 上工作。 有關血腥細節,請參見例如此答案

編輯在 ms-windows 上,似乎還需要將 worker function 放在自己的文件中並導入。 參見例如這里

我找到了使它在 Anaconda 中工作的解決方案。

除了

if __name__ == '__main__':

被稱為(工作人員)的 function 必須在其 own.py 文件中,該文件必須在開始時導入。

我將 RK4 放在我一開始導入的 RK4.py 文件中,但它不起作用,但在我的情況下,來回傳遞值會帶來新的問題......

暫無
暫無

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

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