多进程 Multiprocessing 和多线程 threading 类似, 他们都是在 python 中用来并行运算的. 不过既然有了 threading, 为什么 Python 还要出一个 multiprocessing 呢?

原因很简单, 就是用来弥补 threading 的一些劣势, 即threading的GIL机制无法让thread对于CPU密集型计算没有提速的效果。

1.  使用方法:

(1)和thread比较类似,添加一个进程的方法是:

import multiprocessing as mp

def job(a,d):

print('aaaaa')

if __name__ == '__main__':

#传入1,2

p1 = mp.Process(target=job,args=(1,2))

p1.start()

p1.join()

最终输出结果:

aaaaa

(2)存储进程输出Queue

Queue的功能是将每个核或线程的运算结果放在队里中, 等到每个线程或核运行完毕后再从队列中取出结果, 继续加载运算。原因很简单, 多线程或者多进程调用的函数不能有返回值, 所以使用Queue存储多个线程运算的结果。

import multiprocessing as mp

def job(q):

res = 0

for i in range(1000):

res+=i+i**2+i**3

q.put(res)

if __name__ == '__main__':

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(res1)

print(res2)

print(res1+res2)

(3)对比多线程、多进程、普通的运算时间

import multiprocessing as mp

import threading as td

import time

def job(q):

res = 0

for i in range(100000):

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 multitd():

q = mp.Queue()

p1 = td.Thread(target=job,args=(q,))

p2 = td.Thread(target=job,args=(q,))

p1.start()

p2.start()

p1.join()

p2.join()

res1 = q.get()

res2 = q.get()

print('multitd:',res1+res2)

def normal():

res = 0

for _ in range(2):

for i in range(100000):

res = i+i**2+i**3

print('normal:',res)

if __name__ == '__name__':

st = time.time()

normal()

st1 = time.time()

print('The time consumption(normal):',st1-st)

multitd()

st2 = time.time()

print('The time consumption(multitd):',st2-st1)

multicore()

st3 = time.time()

print('The time consumption(multicore):',st3-st2)

显示结果

"""# range(1000000)

('normal:', 499999666667166666000000L)

('normal time:', 1.1306169033050537)

('thread:', 499999666667166666000000L)

('multithread time:', 1.3054230213165283)

('multicore:', 499999666667166666000000L)

('multicore time:', 0.646507978439331)"""

可看出,multicore的速度>普通>multitd的速度。

(4)进程池pool

Pool默认调用是CPU的核数,传入processes参数可自定义CPU核数

map() 放入迭代参数,返回多个结果

import multiprocessing as mp

def job(x):

return x*x

def multicore():

#定义一个pool

pool = mp.Pool()

res = pool.map(job,range(10))

print(res)

if __name__ == '__main__':

multicore()

返回结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[Finishedin 0.6s]

有了池子之后,就可以让池子对应某一个函数,我们向池子里丢数据,池子就会返回函数返回的值。 Pool和之前的Process的不同点是丢向Pool的函数有返回值,而Process的没有返回值。

接下来用map()获取结果,在map()中需要放入函数和需要迭代运算的值,然后它会自动分配给CPU核,返回结果。

3.自定义核数量

自定义核数量为3

def multicore():

pool = mp.Pool(processes=3) # 定义CPU核数量为3

res = pool.map(job, range(10))

print(res)

4.apply_async()只能放入一组参数,并返回一个结果,如果想得到map()的效果需要通过迭代

#应用apply_async()输出多个结果

multi_res = [pool.apply_async(job,(i,)) for i in range(10)]

#取出参数

print([res.get() for res in multi_res]

结果:

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

[0,1, 4, 9, 16, 25, 36, 49, 64, 81]

[Finishedin 0.9s]

(5)共享内存

这节我们学习如何定义共享内存。只有用共享内存才能让CPU之间有交流。

通过Value数据存储在一个共享的内存表中。

import multiprocessing as mp

value1 = mp.Value('i', 0)

value2 = mp.Value('d', 3.14)

其中:“i”是int型(带符号整型);"d"是双精浮点型(double)

各参数代表的数据类型

(6)进程锁

没有进程锁

import multiprocessing as mp

import time

# 我们定义了一个共享变量v,两个进程都可以对它进行操作。

# 在job()中我们想让v每隔0.1秒输出一次累加num的结果,

# 但是在两个进程p1和p2 中设定了不同的累加值。所以接

# 下来让我们来看下这两个进程是否会出现冲突。

def job(v,num):

for _ in range(5):

time.sleep(0.1) #暂停0.1s

v.value += num #v.value获取共享变量值

print(v.value)

def multicore():

v = mp.Value('i',0) #定义共享变量

#一个迭代值是1,一个迭代值是3

p1 = mp.Process(target=job,args=(v,1))

p2 = mp.Process(target=job,args=(v,3))

#不加进程锁,看如何抢资源

p1.start()

p2.start()

p1.join()

p2.join()

if __name__ == '__main__':

multicore()

在上面的代码中,我们定义了一个共享变量v,两个进程都可以对它进行操作。 在job()中我们想让v每隔0.1秒输出一次累加num的结果,但是在两个进程p1和p2 中设定了不同的累加值。所以接下来让我们来看下这两个进程是否会出现冲突。

1

5

9

13

17

4

8

12

16

20

很明显,出现了进程冲突。

为了解决上述不同进程抢共享资源的问题,我们可以用加进程锁来解决。

import multiprocessing as mp

import time

# 我们定义了一个共享变量v,两个进程都可以对它进行操作。

# 在job()中我们想让v每隔0.1秒输出一次累加num的结果,

# 但是在两个进程p1和p2 中设定了不同的累加值。所以接

# 下来让我们来看下这两个进程是否会出现冲突。

#加入进程锁

def job(v,num,l):

l.acquire() # 锁住

for _ in range(5):

time.sleep(0.1) #暂停0.1s

v.value += num #v.value获取共享变量值

print(v.value)

l.release() #释放

def multicore():

v = mp.Value('i',0) #定义共享变量

l = mp.Lock()

#一个迭代值是1,一个迭代值是3

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[Finishedin 1.3s]

莫烦python看的顺序_莫烦Python笔记__Python多进程技巧相关推荐

  1. python方法解析顺序_浅谈Python的方法解析顺序(MRO)

    方法解析顺序, Method Resolution Order 从一段代码开始 考虑下面的情况: class A(object): def foo(self): print('A.foo()') cl ...

  2. python 语句执行顺序_一个针对 Python 语句执行顺序的练习

    摘自 Fluent Python evalsupport.py print(' evalsupport module start') def deco_alpha(cls): print(' deco ...

  3. 看python源代码的顺序_查看“Python-2020-fall”的源代码

    因为以下原因,您没有权限编辑本页: 您所请求的操作仅限于该用户组的用户使用:用户 您可以查看与复制此页面的源代码.== Python程序设计课程主页(2020年秋季学期) == Teacher: [h ...

  4. python 编程该看那些书籍_初学者自学Python要看什么书?

    原标题:初学者自学Python要看什么书? 人工智能时代的来临让Python崭露头角,语法简洁.功能强大的特性更是吸引了很多人学习Python.由于某些条件的限制,有部分人选择自学Python,而需要 ...

  5. python 改变词典顺序_按词典顺序排列的功率集

    python 改变词典顺序 Description: 描述: This is a standard interview problem to find out the power sets in le ...

  6. python小白应该看什么书_小白学python看什么书

    适合小白阅读的python入门书有 <Python编程 从入门到实战> 本书中涵盖的内容是比较精简的,没有艰深晦涩的概念,最重要的是每个小结都附带有"动手试一试"环节, ...

  7. python包括哪些部分_第一部分 Python基础篇

    第⼀一部分 Python基础篇 1. 为什什么学习Python? 朋友推荐,比较简单易学,生态圈比较强大 发展趋势:人工智能.数据分析 2. 通过什什么途径学习的Python? 廖雪峰.网络博客.相关 ...

  8. python变量定义大全_详解python变量与数据类型

    这篇文章我们学习 Python 变量与数据类型 变量 变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念,变量可以通过变量名访问.在 Python 中 变量命名规定,必须是大小写英文,数字 ...

  9. python怎么求指数_求指数 python

    softmax用于多分类过程中最后一层,将多个神经元的输出,映射到(0, 1)区间内,可以看成概率来理解,从而来进行多分类! softmax函数如下: 更形象的如下图表示: softmax 直白来说就 ...

  10. python实现数据可视化_使用Matplotib python实现数据可视化

    python实现数据可视化 I Feel: 我觉得: In today's digital world data has become as important as air. Machines &a ...

最新文章

  1. 我的实用设计模式 - Simple Factory和Reflection
  2. linux 文本处理 awk 几个特殊的内置变量
  3. http的请求类型 get 、post、delete、put、patch之间的区别
  4. python时间重叠_最常见的重叠范围-Python3.x
  5. 用python计算pi的值_如何使用python中的series计算pi的值?
  6. Python 谁是小偷? 嫌疑人A、B、C、D的笔录如下,其中三人为真,一人为假:
  7. linux解压rar文件权限,linux下使用unrar命令解压*.rar格式文件
  8. 基于JAVA+SpringMVC+Mybatis+MYSQL的个人记账管理系统
  9. github上下载别人的vue项目,本地运行
  10. linux下C转码函数:iconv使用
  11. Oracle下载 OPatch
  12. java redis3.0_Java + Redis(第三章)
  13. android 音效,音效  |  Android 开源项目  |  Android Open Source Project
  14. 交通灯matlab程序,毕业论文设计(交通灯).doc
  15. 【光纤通信】实验二、C语言实现HDB3编码
  16. Kali Linux安装GVM 20.08(前OpenVas)
  17. 树形表格TreeGrid
  18. 烟台大学—贺利坚的计算机课程教学链接
  19. canvas - 绘制图片,图片变模糊问题解决)
  20. Struts2报错Caused by: java.lang.NoSuchMethodException: bean.Student.init()

热门文章

  1. 【EJB学习笔记】——EJB开发环境搭建(Eclipse集成JBoss)
  2. java编译器eclipse_java编译器eclipse
  3. CuteFTP下载大文件时报错
  4. 计算机的硬盘e找不到,计算机D驱动器E驱动器突然消失. 小编帮你找回了
  5. 微软开放必应搜索引擎核心算法
  6. 小小串联电阻,大大的作用
  7. Everything搜索工具不能搜索硬盘文件夹问题解决
  8. Linux内核启动过程学习
  9. Dreamweaver网页课设做家乡网站
  10. dnf脚本是php,易语言:DNF自动脚本