python - 当输入列表超过一定长度时,多处理代码会挂起

标签 python multiprocessing

我一直在研究多处理模块,以便从实现方面获得更好的理解。下面的代码执行以下串行然后并行的方式:

生成一组随机数。每个数字都用作指数函数中的常数。目标是为每个随机数找到一个所需的标量,使指数函数的积分为 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/

相关文章:

python - Python tkinter 中的多处理

python - 并行重新分配大型数组中的元素

python - 如何在 Python 3 中重用进程池进行并行编程

python - 将字符串从 C 传递到 Python 进行多处理,无需进行额外的复制

python - Google Sheets API v4 评论数据到 pandas df,而不是值

python - 在Python中有一个元组列表,对于每个元组,希望将x[0]和x[1]放入Excel电子表格的A列和B列中

python - PyPDF2 复制后返回空白 PDF

python - 使用 Python 和 pyathenajdbc 连接 Athena

python - 使用 python file_dialog() 从 Scientific Linux 访问 Windows 共享上的网络文件夹

c - 使用 vfork() 和 -lpthread 的孙子的 getpid() 结果不正确