Python 脚本在 运行 进程后获取队列条目时挂起
Python script hangs when getting queue entries after running Process
我正在尝试学习 Python 3 中的多处理模块。我的玩具问题是 Lennard-Jones 势中粒子轨迹的欧拉积分,我已将其添加到下面的代码块中.
当mpSwich
为False
时,函数Integrate
在当前进程中为运行,代码如您所料执行。否则 Integrate
在子进程中是 运行 并且脚本挂起。当我使用调试器逐步执行此操作时,当我尝试使用 results.update(outputQueue.get())
从子进程中获取轨迹时,似乎发生了挂起。我不完全相信这是挂起的原因而不是挂起的症状,无论哪种方式我都在努力找出问题的根源。我计划 运行 一个时间步长值 Dt
的子进程,然后并行地,Dt
的多个值。
import numpy as np
import matplotlib.pyplot as plt
import multiprocessing as mp
# calculate position and momentum
def Integrate(Dt, output):
T = np.float64(100.0)
N = np.int(T/Dt)
q = np.zeros((N, 3))
p = np.zeros((N, 3))
q[0, :] = 1.9
p[0, :] = -0.0001
LJ = lambda x: x**-12 - 2.0*x**-6
M = np.float64(45.0)
# Euler method
for nn in range(N - 1):
q[nn + 1, :] = q[nn, :] + Dt*p[nn, :]
h = np.abs(q[nn + 1, :] - q[nn, :]) * np.ones(3)
dphidq = (LJ(q[nn, :] + h) - LJ(q[nn, :] - h))/(2.0*h)
p[nn + 1, :] = p[nn, :] - Dt*dphidq/M
# store results in queue
outdict = {}
outdict[Dt] = [q, p]
output.put(outdict)
# manage simulation
mpSwitch = True
if mpSwitch:
# launch process to perform simulation
if __name__ == '__main__':
outputQueue = mp.Queue()
p = mp.Process(target = Integrate, args = (np.float64(0.001), outputQueue))
p.start()
results = {}
results.update(outputQueue.get())
p.join()
else:
# perform simulation in current process
outputQueue = mp.Queue()
Integrate(np.float64(0.001), outputQueue)
results = {}
results.update(outputQueue.get())
#plot results
plt.figure(1)
plt.clf()
plt.title('Phase Diagram')
plt.plot(results[0.001][0][:, 0], results[0.001][1][:, 0], '.-')
plt.xlabel('Coordinate')
plt.ylabel('Momentum')
您是否尝试过使用 concurrent.futures 包中的 ThreadPoolExecutor 并查看是否可以为同一示例重现该行为?
这个问题原来是我犯的一个愚蠢的错误。这是一个范围问题,如果绘图部分移动到 if __name__ == '__main__'
语句下,那么这段代码似乎可以工作。
我正在尝试学习 Python 3 中的多处理模块。我的玩具问题是 Lennard-Jones 势中粒子轨迹的欧拉积分,我已将其添加到下面的代码块中.
当mpSwich
为False
时,函数Integrate
在当前进程中为运行,代码如您所料执行。否则 Integrate
在子进程中是 运行 并且脚本挂起。当我使用调试器逐步执行此操作时,当我尝试使用 results.update(outputQueue.get())
从子进程中获取轨迹时,似乎发生了挂起。我不完全相信这是挂起的原因而不是挂起的症状,无论哪种方式我都在努力找出问题的根源。我计划 运行 一个时间步长值 Dt
的子进程,然后并行地,Dt
的多个值。
import numpy as np
import matplotlib.pyplot as plt
import multiprocessing as mp
# calculate position and momentum
def Integrate(Dt, output):
T = np.float64(100.0)
N = np.int(T/Dt)
q = np.zeros((N, 3))
p = np.zeros((N, 3))
q[0, :] = 1.9
p[0, :] = -0.0001
LJ = lambda x: x**-12 - 2.0*x**-6
M = np.float64(45.0)
# Euler method
for nn in range(N - 1):
q[nn + 1, :] = q[nn, :] + Dt*p[nn, :]
h = np.abs(q[nn + 1, :] - q[nn, :]) * np.ones(3)
dphidq = (LJ(q[nn, :] + h) - LJ(q[nn, :] - h))/(2.0*h)
p[nn + 1, :] = p[nn, :] - Dt*dphidq/M
# store results in queue
outdict = {}
outdict[Dt] = [q, p]
output.put(outdict)
# manage simulation
mpSwitch = True
if mpSwitch:
# launch process to perform simulation
if __name__ == '__main__':
outputQueue = mp.Queue()
p = mp.Process(target = Integrate, args = (np.float64(0.001), outputQueue))
p.start()
results = {}
results.update(outputQueue.get())
p.join()
else:
# perform simulation in current process
outputQueue = mp.Queue()
Integrate(np.float64(0.001), outputQueue)
results = {}
results.update(outputQueue.get())
#plot results
plt.figure(1)
plt.clf()
plt.title('Phase Diagram')
plt.plot(results[0.001][0][:, 0], results[0.001][1][:, 0], '.-')
plt.xlabel('Coordinate')
plt.ylabel('Momentum')
您是否尝试过使用 concurrent.futures 包中的 ThreadPoolExecutor 并查看是否可以为同一示例重现该行为?
这个问题原来是我犯的一个愚蠢的错误。这是一个范围问题,如果绘图部分移动到 if __name__ == '__main__'
语句下,那么这段代码似乎可以工作。