<Notes>Python_Multiprocessing

前言

基本学习目标

  • 学习Python Multiprocessing 基本语法
  • 分析对比多进程和多线程,以及二者适用场景
  • 使用多进程编写serial通信代码

学习笔记

Multiprocessing核心函数大致用法

创建进程:

  • 用法分析:python创建进程和创建线程的方法基本一致(python简化了很多重复的东西);

  • 代码分析:

    import multiprocessing
    
    
    def job():
        print('aaaa')
        # 查看当前线程数
    
    if __name__ == '__main__':
        p1 = multiprocessing.Process(target=job)
        p1.start()
        p1.join()
    

Queue进程输出:

  • 功能分析:

  • 用法分析

  • 代码分析:

import multiprocessing
  
  def job(q):
      res = 0
      for i in range(1000):
          res += i+i**2+i**3
      q.put(res)  #queue
  
  if __name__ == '__main__':
      q = multiprocessing.Queue()
      p1 = multiprocessing.Process(target=job,args=(q,)) 
      #这里args只有一个值的时候必须(q,)这样写,说明args是可以迭代的,后续可以更新
      p2 = multiprocessing.Process(target=job,args=(q,))
      p1.start()
      p2.start()
      p1.join()
      p2.join()
      res1 = q.get()
      res2 = q.get()
      print(res1+res2)

分析:Multiprocessing中已经嵌套了Queue

多线程多进程效率对比:

  • 功能分析:

  • 用法分析

  • 代码分析:

    import multiprocessing as mp
    import threading as td
    import time
    
    def job(q):
        res = 0
        for i in range(1000000):
            res += i+i**2+i**3
        q.put(res) # queue
    
    def multicore():
        q = mp.Queue()
       
        p1 = mp.Process(target=job, args=(q,))   
        p2 = mp.Process(target=job, args=(q,))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
        res1 = q.get()
        res2 = q.get()
        print('multicore:' , res1+res2)
    
    def normal():
        res = 0
        #’_’ 是一个循环标志,也可以用i,j 等其他字母代替
        for _ in range(2):
            for i in range(1000000):
                res += i+i**2+i**3
        print('normal:', res)
    
    def multithread():  
        q = mp.Queue()
        t1 = td.Thread(target=job, args=(q,))
        t2 = td.Thread(target=job, args=(q,))
        t1.start()
        t2.start()
        t1.join()
        t2.join()
        res1 = q.get()
        res2 = q.get()
        print('multithread:', res1+res2)
    
    if __name__ == '__main__':
        st = time.time()
        normal()
        st1= time.time()
        print('normal time:', st1 - st)
        multithread()
        st2 = time.time()
        print('multithread time:', st2 - st1)
        multicore()
      print('multicore time:', time.time()-st2)
    

    分析:多进程>多线程>normal

进程池pool:

  • 功能分析:进程池pool是,你可以把运算放进pool中,python会自动分配进程以及运算结果;

  • 代码分析:

    import multiprocessing as mp
    
    def job(x):
        return x*x
    
    def multicore():
        pool = mp.Pool(processes=2)
        res = pool.map(job, range(10))
        print(res)
        res = pool.apply_async(job, (2,))
        print(res.get())
        multi_res =[pool.apply_async(job, (i,)) for i in range(10)]
        print([res.get() for res in multi_res])
    
    if __name__ == '__main__':
        multicore()
    

在这里插入图片描述

分析:进程池pool是一个计算结果的很好办法,他会选择最大进程数。

共享内存shared memory:

  • 功能分析:在多进程中,每一个进程都有自己的内存空间;此事使用全局变量是行不通的,要用到shared memory;
  • 代码分析:
import multiprocessing

#共享的值  d表示形式 小数,i代码整数...    1是传入的值
value = multiprocessing.Value('d',1)

#这是共享列表  这里Array只能是一维
array = multiprocessing.Array('i',[1,2,3])

在这里插入图片描述

分析:只有shared memory才能实现进程间的交流

Lock:

  • 功能分析:lock是在shared memory的基础上使用的;

  • 代码分析:

    import multiprocessing
    import time
    
    def job(v,num,l):
        l.acquire()
        for _ in range(10):
            time.sleep(0.1)
            v.value += num
            print(v.value)
        l.release()
    
    def multicore():
        l = multiprocessing.Lock()
        v = multiprocessing.Value('i',0)
        p1 = multiprocessing.Process(target=job,args=(v,1,l))
        p2 = multiprocessing.Process(target=job, args=(v, 3, l))
        p1.start()
        p2.start()
        p1.join()
        p2.join()
    
    if __name__ == '__main__':
        multicore()
    

其他总结

print(multiprocessing.cpu_count()) output:8 ,四核心八线程的电脑

其他思考

1、如何选择最优进程数?

分析:在任务量较大时,选择电脑核数的线程;四核心八线程(超线程技术)在多进程中就是8个cpu处理;使用pool选择最优进程。

2、多线程其实是一个时间运行一个线程,这样比如全双工通信,在python使用多线程处理,其实还是半双工的?

分析:其实是半双工(假全双工)。

3、如何查看当前进程数?

Pid:Return the process ID,通过 os module下的os.getpid()获取进程号。

学习总结

  • RGB三个通道相同就是灰色(0-255)
  • 多进程不是能加速所有的计算,因为调用进程也是要耗费时间的,所以在计算量不大的时候使用多进程反而会耗时
  • 高io吞吐多线程肯定有有优势,
  • 多进程一定要在main下运行,格式要求
  • 多核,每个核有单独的运算空间和运算能力

参考资料

视频资料

1、【莫烦Python】Multiprocessing 让你的多核计算机发挥真正潜力 Python:https://www.bilibili.com/video/BV1jW411Y7pv.
​ 教程代码:https://github.com/MorvanZhou/tutorials/tree/master/multiprocessingTUT.

文档资料

官方资料

1、
https://docs.python.org/3/library/multiprocessing.html.

多进程笔记github链接: https://github.com/GRF-Sunomikp31/WorkSpace/blob/main/Python/Python_Multiprocessing.md.

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

GRF-Sunomikp31

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

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

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

打赏作者

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

抵扣说明:

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

余额充值