基本知识:

  • 一、什么是多进程 Multiprocessing
  • 二、添加多进程 Process
  • 三、存储进程输出 Queue
  • 四、效率对比 threading & multiprocessing
  • 五、进程池 Pool
  • 六、共享内存 shared memory
  • 七、进程锁 Lock

一、什么是多进程 Multiprocessing

支持并行运算,充分利用计算机的多核CPU

二、添加多进程 Process

import multiprocessing as mpdef process_job(a,b):print("a:",a)print("b:",b)if __name__=="__main__":p1 = mp.Process(target=process_job,args=(1,2))  # 定义一个进程p1p1.start()                                      # 开启进程p1p1.join()                                       # 将进程p1加入到主进程

三、存储进程输出 Queue

多进程调用的函数不能有返回值,故使用Queue存储结果。

import multiprocessing as mpdef process_job(q):res = 0for i in range(10):res += iq.put(res)if __name__=="__main__":q = mp.Queue()p1 = mp.Process(target=process_job,args=(q,))  # 注意args必须是可迭代的类型,但只有一个参数的时候,要加一个逗号p2 = mp.Process(target=process_job,args=(q,))p1.start()p2.start()p2.join()p1.join()print("res1:",q.get())print("res2:",q.get())

四、效率对比 threading & multiprocessing

import multiprocessing as mp
import threading as td
import timedef job(q):res = 0for i in range(100000):res += i + i**2 + i**3q.put(res)def multiProcess():    # 多进程运算q = mp.Queue()p1 = mp.Process(target=job,args=(q,))  p2 = mp.Process(target=job,args=(q,))  p1.start()p2.start()p2.join()p1.join()print("multiProcess_res:",q.get()+q.get())def multiThread():    # 多线程运算q = mp.Queue()t1 = td.Thread(target=job,args=(q,))t2 = td.Thread(target=job,args=(q,))t1.start()t2.start()t2.join()t1.join()print("numliThread_res:",q.get()+q.get())def normal():         # 普通运算res = 0for _ in range(2):for i in range(100000):res += i + i**2 + i**3print("normal_res:",res)if __name__=="__main__":t1 = time.time()normal()t2 = time.time()print("normal_time:",t2-t1)multiProcess()t3 = time.time()print("multiProcess_time:",t3-t2)multiThread()t4 = time.time()print("multiThread_time:",t4-t3)

结果:运行时间 多进程 < 多线程 (多线程和普通的运行时间差不多)

normal_res: 49999666671666600000
normal_time: 0.2157750129699707
multiProcess_res: 49999666671666600000
multiProcess_time: 0.14542102813720703
numliThread_res: 49999666671666600000
multiThread_time: 0.2052018642425537

五、进程池 Pool

相当于批量处理多进程
与 Process 不同的是,Pool 有返回值,返回值是一个 list,依次是每个进程执行的结果。

import multiprocessing as mpdef job(x):return x*xdef multicore():pool = mp.Pool(processes=2)       res = pool.map(job, range(10))     # 方式一:使用 pool 的 map 函数print(res)res = pool.apply_async(job, (2,))print(res.get())multi_res =[pool.apply_async(job, (i,)) for i in range(10)]   #方式二:使用 pool 的 apply_async 函数print([res.get() for res in multi_res])if __name__ == '__main__':multicore()

六、共享内存 shared memory

在上一篇文章的第六部分线程锁可以看到,对于一个全局变量,多个线程之间共享全局变量,一个线程对全局变量修改以后,其他线程访问到的是修改后的全局变量,会造成数据的混乱。
与多线程不同的是,多进程不会共享全局变量,多个进程之间不进行交流,任意一个进程对全局变量的修改都不会影响到其他进程对全局变量的访问。
比如:

import multiprocessing as mpdef job1():global Afor i in range(3):A += 1print("Job1:",A)
def job2():global Afor i in range(3):A += 10print("Job2:",A)if __name__=="__main__":A = 0p1 = mp.Process(target=job1)p2 = mp.Process(target=job2)p1.start()p2.start()p2.join()p1.join()

结果:互不影响

1
2
10
3
20
30

因此,需要设置共享内存,让进程之间进行交流:
1、Shared Value
通过使用 Value 将数据存储在一个共享的内存表中

import multiprocessing as mpvalue1 = mp.Value('i', 0)
value2 = mp.Value('d', 3.14)

其中 d 和 i 参数用来设置数据类型的,d 表示一个双精浮点类型,I 表示一个带符号的整型。
2、Shared Array
mutiprocessing中,有还有一个Array类,可以和共享内存交互,来实现在进程之间共享数据

array = mp.Array('i', [1, 2, 3, 4])

这里的Array和numpy中的不同,它只能是一维的,不能是多维的。同样和Value 一样,需要定义数据形式,否则会报错。
参数数据类型表

七、进程锁 Lock

1、不加进程锁

import multiprocessing as mp
import timedef job(v, num):for _ in range(5):time.sleep(0.1) # 暂停0.1秒,让输出效果更明显v.value += num # v.value获取共享变量值print(v.value, end="")def multicore():v = mp.Value('i', 0) # 定义共享变量p1 = mp.Process(target=job, args=(v,1))p2 = mp.Process(target=job, args=(v,3)) # 设定不同的number看如何抢夺内存p1.start()p2.start()p1.join()p2.join()    if __name__ == '__main__':multicore()

结果:进程1和进程2在相互抢着使用共享内存v

1
4
5
8
9
12
13
16
17
20

2、加进程锁

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

结果:显然,进程锁保证了进程p1的完整运行,然后才进行了进程p2的运行

1
2
3
4
5
8
11
14
17
20

一篇文章学习Python中的多进程相关推荐

  1. 一篇文章学习Python中的多线程

    基本知识: 一.什么是多线程Threading 二.添加线程Thread 三.join功能 四.存储进程结果Queue 五.GIL不一定有效率 六.线程锁 Lock 一.什么是多线程Threading ...

  2. Python基础学习-Python中最常见括号()、[]、{}的区别 2015-08-13 07:54 by xuxiaoxiaoxiaolu, 1138 阅读, 0 评论, 收藏, 编辑 Pytho

    Python基础学习-Python中最常见括号().[].{}的区别 2015-08-13 07:54 by xuxiaoxiaoxiaolu, 1138 阅读, 0 评论, 收藏, 编辑 Pytho ...

  3. python中continue用法案例_记录今天学习python中for与while循环针对break和continue的用法...

    python中有两个主要的循环for与while,其中针对这两个循环有两种不同的中断用法break与continue. 首先先看下面的循环代码: 1: for i in range(10):#变量i带 ...

  4. Python 中的多进程(进程之间的通信)

    文章目录 在进程之间共享数据 共享内存 服务器进程 进程之间的通信 队列 管道 这篇文章将会讲解在 Python 中使用 多进程模块时在进程之间共享数据和消息传递的概念. 在多处理中,任何新创建的进程 ...

  5. python多线程好还是多协程好_深入浅析python中的多进程、多线程、协程

    进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...

  6. 中英文学习Python中的字典类型

    中英文学习Python中的字典类型 请看视频: Python中的字典类型,中英文学习,并简单介绍了哈希

  7. python廖雪峰_【Python】python中实现多进程与多线程

    进程与线程 进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1].比如,打开一个word文件就是启动了一个word进程. 线程(thread)是进程内的子任务.比如word中 ...

  8. async python两个_【Python】python中实现多进程与多线程

    进程与线程 进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1].比如,打开一个word文件就是启动了一个word进程. 线程(thread)是进程内的子任务.比如word中 ...

  9. python 的库如何开发_一篇文章入门Python生态系统

    译者按:原文写于2011年末,虽然文中关于Python 3的一些说法可以说已经不成立了,但是作为一篇面向从其他语言转型到Python的程序员来说,本文对Python的生态系统还是做了较为全面的介绍.文 ...

最新文章

  1. 归档 OmniFocus 中已完成的任务到 印象笔记 Evernote
  2. pytorch训练过程中loss出现NaN的原因及可采取的方法
  3. Leaflet中使用leaflet-search插件实现搜索定位效果
  4. 一键移除所有权限密码,不到1MB!
  5. C#中HashTable、Dictionary、ConcurrentDictionary区别
  6. GC之详解CMS收集过程和日志分析
  7. docker进阶与实战 3 理解docker镜像
  8. 列存储中常用的数据压缩算法
  9. 一个数根号3怎样用计算机计算,手机计算器怎样打出根号3
  10. Docker基础介绍(二)
  11. LincSNP:lncRNA相关SNP位点数据库
  12. Kubeadm搭建高可用K8S(四)Dashboard安装配置
  13. android 高德地图动画,使用MotionLayout实现高德地图bottomSheets效果
  14. ​left join 和 left semi join区别 ​
  15. python全排列,递归
  16. 【FPGA学习笔记】(一)什么是FPGA?和单片机ARM有什么区别?
  17. linux centos7 hadoop2.7.7HA集群搭建
  18. shell脚本案例(一):常见运维面试题
  19. ILSVRC2016目标检测任务回顾——视频目标检测(VID)
  20. 手把手教你玩转Vue

热门文章

  1. Linux驱动开发中与设备树相关的6种debug方法
  2. 没有串口,如何打印单片机调试信息?
  3. 小米12比我的小米10还便宜
  4. go设置后端启动_为什么 Rubyists 应该考虑学习 Go
  5. 学生信息系统求助_一个学生信息录入和查询的系统
  6. 指令系统——数据存放、指令寻址(详解)
  7. LeetCode 1885. Count Pairs in Two Arrays(二分查找)
  8. LeetCode 1602. 找到二叉树中最近的右侧节点(BFS)
  9. LeetCode 514. 自由之路(记忆化递归 / DP)
  10. LeetCode 694. 不同岛屿的数量(BFS/DFS+set)