Python中关于多进程的问题如何解决?

我编了一个图像处理的程序,因为运行比较慢,所以去网上找了一下用多进程处理的方法,结果运行到图像合成的步骤就出错了,不知道怎么回事,代码如下:
if name == ‘main’:
img = cv2.imread(’./2.jpg’, cv2.IMREAD_ANYCOLOR)
image_0_1 = img/255
image = list(cv2.split(image_0_1))

gf1=Process(target=lvboout,kwargs={‘img’:image[0],})
gf2=Process(target=lvboout,kwargs={‘img’:image[1],})
gf3=Process(target=lvboout,kwargs={‘img’:image[2],})

gf1.start()
gf2.start()
gf3.start()
gf1.join()
gf2.join()
gf3.join()


‘’‘gf1=lvboout(image[0])
gf2=lvboout(image[1])
gf3=lvboout(image[2])’’’
gf = cv2.merge([gf1, gf2, gf3])
引号部分是原程序,运行没问题,错误提示是:mv is not a numpy array,neither a scalar
Python中关于多进程的问题如何解决?


3 回复

Python里搞多进程,最直接的就是用multiprocessing模块。它基本模仿threading的API,但创建的是真正的进程,能绕过GIL充分利用多核。

核心就这几步:

  1. import multiprocessing
  2. 把你想并行的任务写成一个函数
  3. Process类创建进程对象,或者用Pool来管理进程池
  4. 启动(.start())和等待(.join()),或者用Poolmap/apply方法

给你个最清楚的例子,计算数字平方:

import multiprocessing

def compute_square(number):
    """这就是要在进程里跑的任务"""
    result = number * number
    print(f"{number} 的平方是 {result}")
    return result

if __name__ == '__main__':  # 这行在Windows下必须加,防递归创建进程
    numbers = [1, 2, 3, 4, 5]
    
    # 方法1:用Process一个个创建
    processes = []
    for n in numbers:
        p = multiprocessing.Process(target=compute_square, args=(n,))
        processes.append(p)
        p.start()
    
    for p in processes:
        p.join()
    
    # 方法2:用进程池Pool更省事(实际更常用)
    with multiprocessing.Pool(processes=3) as pool:  # 开3个进程
        results = pool.map(compute_square, numbers)
        print(f"所有结果: {results}")

关键点:

  • 进程间内存不共享,传数据用QueuePipe
  • 如果只是CPU密集型计算,用Pool.map最省心
  • 记得用if __name__ == '__main__':保护入口

总结:CPU密集型任务用multiprocessing,IO密集型考虑asyncio或threading。


试下把入参转成 numpy array

我调用 gf1 的数据看了一下,是返回值的问题,直接用 process 赋值的话,最后返回的是进程数据,不是函数的返回值。我去网上查了一下后,改用 pool 进程池,程序改为如下:
pool = multiprocessing.Pool(processes = 3)
results = []
for i in range(3):
results.append(pool.apply_async(lvboout,(image[i],)))
pool.close()
pool.join()

gf1 = results[0].get()
gf2 = results[1].get()
gf3 = results[2].get()
最后得到的 gf1,gf2 和 gf3 就是函数的返回值了,接下来也没问题了。

回到顶部