12. 多进程

python多进程

区别于多线程:多进程是实实在在的将计算任务分配到计算机的不同的核或者说处理机上,实现进程的并行操作,能够大大提高项目的执行效率和速度

1. 创建多线程以及join()方法:语法结构与threading模块近乎相同

import multiprocessing as mp
def job(data):
    p = mp.Process(target=job, args=(data,), name='p1')
    p.start()
    pass

if __name__ == "__main__":
    p = mp.Process(target=job, args=(data,), name='p1')
    p.start()
    p.join()
  • mp.Process():创建新进程,相关参数与 threading.Thread 完全相同

  • 包含多进程的项目,一定要在py文件中才能运行出来,而且要求包含if __name__ == "__main__":,必须从主进程中创建多进程,可以有以下两种方式

    # Method 1: 主进程中直接调用
    def fun():
        pass
    if __name__ == "__main__":
        p = mp.Process(target=job, args=(data,), name='p1')
        p.start()
    
    # Method 2: 主进程中函数调用
    def fun():
        pass
    
    def mpprocess():
        p = mp.Process(target=job, args=(data,), name='p1')
        p.start()
    if __name__ == "__main__":
        mpprocess()  
    

2. mp.Queue():语法结构和threading近乎相同

import multiprocessing as mp

def job(data, q, pname): # q要作为参数传进来
    data = list(data)*2
    q.put({pname : data}) # 保存数据

if __name__ == '__main__':
    q = mp.Queue() # 创建一个用于保存进程运行结果的Queue实例
    p1 = mp.Process(target=job, args=(range(10), q, 'p1'))
    p1.start() 
    p1.join() # 一定要进程完全结束
    print(q.get()) # 取数据
  • 在多进程 multiprocessing 中,要使用 q = mp.Queue() 来创建一个队列实例

3. 进程池

这种方式用于自动优化:连续多次调用一个函数功能 或 连续多次调用不同函数功能

  • mp.Pool().map --> 连续多次调用同一个函数,处理不同的数据

    import multiprocessing as mp
    
    def job(x):
        return data
    
    if if __name__ == '__main__':
        ls = [x1, x2, x3, ...]
        with mp.Pool() as pool:
            res = pool.map(job, ls)
        print('final')
    
    • mp.Pool():创建了一个进程池,默认使用计算机的所有核
    • pool.map(job, ls): 这个方法的功能是将可迭代对象 ls 中的每一项依次传入执行job功能,后台会自动将每一个功能模块分配到多个核中,从而提高效率
    • mp.pool().map注意事项:
      • 上述实例中:map会将ls中的每一项直接传入到job函数中,就意味着ls中的每一项是什么数据类型,job函数每次收到的参数就是什么数据类型!!!
      • 使用进程池完成各种函数功能时,其返回值不需要使用 Queuepool自动集成了数据返回功能
      • 返回结果 res 的返回顺序是严格按照 ls 的数据传入顺序返回的。也就是说就算部分数据的消耗时间远大于其它数据,最后的结果也是按照传入数据的顺序保存的
      • mp.Pool()中指定的函数执行完毕之后才会执行后续的代码模块,相当于自备了一个 join()方法
  • mp.Pool.map() --> 实现连续调用多个函数,不同函数需要不同参数

    def fun1(x):
        return ...
    
    def fun2(X):
        return ...
    
    def fun3(x):
        return ...
    
    def fun(ls):
        f = ls[0]
        para = ls[1]
        return f[0](para)
    
    if __name__ == "__main__":
        ls = [[fun1, x1],
             [fun2, x2],
             [fun3, x3]]
        with mp.Pool() as pool:
            res = pool.map(fun, ls)
        print('final')
    
    • 通过 fun 函数,将所有需要调用的 funx统一集中管理;将各函数和函数需要的变量使用一个列表 ls 保存起来从而达成连续调用不同函数的目的
    • 需要注意的是,map只是将可迭代对象 ls 的每一项作为参数传入,所以在用于统一管理的 fun函数中,需要区分 函数部分 和 参数部分 --> 要注意函数收到的数据传入的类型
  • mp.Pool().starmap()

    def fun_starmap(a, b):
        print("starmap:",a+b)
    
    def fun_map(para):
        a = para[0]
        b = para[1]
        print("map:", a+b)
    
    if __name__ == '__main__':
        ls = [[1, 2],
              [3, 4],
              [5, 6]]
        with mp.Pool(processes=4) as pool:
            pool.starmap(fun_starmap, ls)
        with mp.Pool(processes=4) as pool:
            pool.map(fun_map, ls)
    
    • starmap 在处理传入的ls时的区别:map方法并不限制ls内部的每一项是什么样的数据结构,会直接迭代ls并将每一项传入到指定的函数中; starmap要求 ls 中的每一项都必须是可迭代对象, 而且 stramap将每一个迭代对象拆开后传入到指定的函数中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啥都想学的大学生

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值