我一直在研究多处理模块,以便从实现方面获得更好的理解。下面的代码执行以下串行然后并行的方式:
生成一组随机数。每个数字都用作指数函数中的常数。目标是为每个随机数找到一个所需的标量,使指数函数的积分为 20。
下面的代码似乎可以工作。但是,一旦 num
的值设置为 500,代码就会挂起,我不知道为什么。就其值(value)而言,这是在 Windows 计算机上,所有内容都在 Spyder 中运行。
from scipy import optimize as op
from scipy.integrate import trapz as intg
import numpy as np
import multiprocessing as mp
import random
import timeit
import time
def to_solve(a=None, x=None, y=None):
return intg(a*y, x)-20
def worker(lst, x, out_q):
ans = np.zeros(shape=(len(lst), 2))
for i, a in enumerate(lst):
y = func(a=a, x=x)
ans[i,0] = a
ans[i,1] = op.newton(func=to_solve, x0=1, args=(x, y))
out_q.put(ans)
def func(a=None, x=None):
return 1-np.exp(-a*x)
def main_p(nums):
start = timeit.default_timer()
x = np.linspace(0,100)
procs = []
out_q = mp.Queue()
num_procs = 2
step = int(len(nums)/num_procs)
first = 0
last = 0
for i in range(num_procs):
first = last
last = first+step
if i == num_procs-1:
out = nums[first:]
else:
out = nums[first:last]
p = mp.Process(target=worker, args=(out, x, out_q))
procs.append(p)
p.start()
for p in procs:
p.join()
for i in range(len(procs)):
if i == 0:
results = out_q.get()
else:
results = np.vstack((results, out_q.get()))
results = results[results[:,0].argsort()]
print timeit.default_timer() - start
return results
def main_s(nums):
start = timeit.default_timer()
results = np.zeros(shape=(len(nums),2))
x = np.linspace(0,100)
for i, a in enumerate(nums):
results[i,0] = a
y = func(a=a, x=x)
results[i,1] = op.newton(func=to_solve, x0=1, args=(x,y))
results = results[results[:,0].argsort()]
print timeit.default_timer() - start
return results
if __name__ == '__main__':
num = 400
nums = np.random.rand(1,num)
nums = nums.tolist()[0]
a = main_s(nums)
b = main_p(nums)
最佳答案
您放入队列的对象太大。工作进程在向队列提供数据的缓冲区为空之前不会终止,而直到父进程从队列中读取数据时才会终止,这将在 join() 之后发生,等待 -> 死锁。
描述如下: “An example which will deadlock is the following.” 因此,如果移动循环,问题就会消失
for p in procs:
p.join()
在 for i in range(len(procs)):
之后 - 循环。
关于python - 当输入列表超过一定长度时,多处理代码会挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40333332/