python摸爬滚打之day032 管道 数据共享 进程池
1、进程池
当有成千上万个任务需要被执行的时候,有了进程池我们就不必去创建大量的进程. 首先,创建进程需要消耗时间,销毁进程(空间,变量,文件信息等等的内容)也需要消耗时间, 第二即便开启了成千上万的进程,操作系统也不能让他们同时执行,维护一个很大的进程列表的同时,调度的时候,还需要进行频繁切换并且记录每个进程的执行节点, 这样反而会影响程序的效率。
创建一个有固定数量的进程池, 执行任务的时候就拿池中的进程来处理任务,等到处理完毕,进程并不关闭,而是将进程再放回进程池中继续等待任务, 可以减少创建进程的开支. 这样不会增加操作系统的调度难度,还节省了开闭进程的时间,也一定程度上能够实现并发效果.
使用进程池来实现并发效果, 减少创建进程的开支, 提高效率.
map()方法: 异步调用进程, map自带join()的功能.
import time
from multiprocessing import Pool,Process def func1(i):
numb = 0
for j in range(5):
numb += i if __name__ == '__main__': p_lst = []
s_time = time.time()
for i in range(500):
p = Process(target=func1,args=(i,))
p.start()
p_lst.append(p)
[pp.join() for pp in p_lst]
e_time = time.time()
dis_time = e_time - s_time
print("非进程池",dis_time) # 9.458896160125732 处理时间 # --------------------------------------------------------------------------------- pool = Pool(4)
ps_time = time.time()
pool.map(func1, range(100)) # 把可迭代对象的每一个元素都作为参数扔给func1
pe_time = time.time()
dis_time = pe_time - ps_time
print("进程池",dis_time) # 0.07204794883728027 处理时间
进程池map方法
apply()方法: 提供一个同步串行的方法.
import time
from multiprocessing import Pool,Process def func1(i):
numb = 0
for j in range(5):
numb += i
time.sleep(0.5)
return numb if __name__ == '__main__': pool = Pool(4) for i in range(10):
print(i)
ret = pool.apply(func1, args=(i,)) # apply提供的是一个同步串行的执行方法.
# 进程1 执行完任务后, ret 获取到数据, 第二个进程才开始执行任务. print(ret)
进程池apply同步调用
apply_async()方法: 进程池异步调用方法.
注意: 在使用进程池异步调用时, 主进程结束时, 所有的子进程也跟着一起结束了(后台全部关闭), 所以主程序必须得先 join() , 等待子进程结束.
使用apply_async()异步调用时, 主程序必须使用 join() 方法, 等待进程池内的任务都处理完, 才能用get()获取结果.
使用map()异步调用时, 不用写 join() 方法, map()会自动 join().
import time
from multiprocessing import Pool,Process def func1(i):
numb = 0
for j in range(5):
numb += i
time.sleep(1)
return numb if __name__ == '__main__': pool = Pool(4)
ret_lst = []
for i in range(10): # 相当于发布10个任务, 4个进程都过来拿任务
print(i)
res = pool.apply_async(func1,args=(i,)) # 各进程都是异步状态
ret_lst.append(res) # 这一步, 是把所有的res的执行对象都先放进列表里(包括那些没有结果的对象,
# 即使后面6个任务都没有执行,但是都是先把执行对象放进列表里) pool.close() # 不是关闭进程池, 而是结束进程池接受任务, 确保没有任务再传过来
pool.join() # 感知进程池中的任务已经结束, 只有进程池结束接收任务, 才能感知进程池中的任务结束, 所以必须加 close(). for res in ret_lst:
print(res.get()) # 前4个有结果, 用get()方法获取到结果后, 一直阻塞在后六个处,直到结果传进来执行对象中
apply_async异步调用
2、回调函数
回调函数在主进程中被执行的, 子进程执行完相应的代码后, 返回主进程去执行回调函数, 它帮我们省略了主进程自身调用函数的这一步骤.
from multiprocessing import Process,Pool def func1(n):
return n * n def call_back_func(ret): # 这里的ret 传的是func1的结果.
with open("回调内容","w") as f:
f.write(str(ret)) if __name__ == '__main__': pool = Pool(4)
ret = pool.apply_async(func1,args=(25,),callback=call_back_func)
# callback后面跟回调函数, 即把func1的结果传进callback回调函数中去执行,因为调用者拿不到
# 回调函数的返回值, 所以只能将返回值写进文件或者数据库里. print(ret.get())
进程池回调函数
3、进程间的通信
多进程共同去处理共享数据的时候,就和我们多进程同时去操作一个文件中的数据是一样的,不加锁就会出现错误的结果,进程不安全的,所以也需要加锁
数据共享----Manager模块
给Manager对象里面传入你要共享的数据, 然后操作数据时一样要上锁、解锁.
from multiprocessing import Process,Lock,Manager def func1(dic,loc):
with loc: # with loc 做了两件事: loc.acquire() 和 loc.release(), 自动上锁和解锁
dic["numb"] -= 1 if __name__ == '__main__':
m = Manager()
loc = Lock()
dic = m.dict({"numb": 100})
p_lst = []
for i in range(100):
p = Process(target=func1, args=(dic,loc))
p.start()
p_lst.append(p)
[pp.join() for pp in p_lst]
print(">>>>>>",dic["numb"])
Manager数据共享
python摸爬滚打之day032 管道 数据共享 进程池的更多相关文章
- 进程同步控制(锁,信号量,事件), 进程通讯(队列和管道,生产者消费者模型) 数据共享(进程池和mutiprocess.Pool模块)
参考博客 https://www.cnblogs.com/xiao987334176/p/9025072.html#autoid-1-1-0 进程同步(multiprocess.Lock.Semaph ...
- Python开发基础-Day32 进程间通信、进程池、协程
进程间通信 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的. 进程队列queue 不同于线程queue,进程 ...
- day32 通道 数据共享 进程池
1.管道 格式: conn1,conn2 = Pipe() 管道的两端可以进行全双工通信 如图 进程2创建了管道,它就拥有管道两端的信息,每个端点都能收发信息,它把端点信息传给进程1和进程3 ,它 ...
- python学习笔记——multiprocessing 多进程组件 进程池Pool
1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...
- Python 3 并发编程多进程之进程池与回调函数
Python 3 进程池与回调函数 一.进程池 在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间.多进程是实现并发的手段之一,需要注意 ...
- day 32 管道,信号量,进程池,线程的创建
1.管道(了解) Pipe(): 在进程之间建立一条通道,并返回元组(conn1,conn2),其中conn1,conn2表示管道两端的连接对象,强调一点:必须在产生Process对象之前产生管道. ...
- Python Django 协程报错,进程池、线程池与异步调用、回调机制
一.问题描述 在Django视图函数中,导入 gevent 模块 import gevent from gevent import monkey; monkey.patch_all() from ge ...
- python 之并发编程更新版进程池与进程池比较与回调函数
一.更新版进程池与进程池比较 from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor import os, tim ...
- 在python中使用concurrent.futures实现进程池和线程池
#!/usr/bin/env python # -*- coding: utf-8 -*- import concurrent.futures import time number_list = [1 ...
随机推荐
- vue-i18n国际化在data中切换不起作用
vue-i18n是一个针对于vue的国际化插件,使用非常简单,具体使用方式看我细细道来. 实现方式 1. 下载包 npm install vue-i18n 2. 配置 在main.js文件中加入如下配 ...
- 论文阅读 | A Curriculum Domain Adaptation Approach to the Semantic Segmentation of Urban Scenes
paper链接:https://arxiv.org/pdf/1812.09953.pdf code链接:https://github.com/YangZhang4065/AdaptationSeg 摘 ...
- vue项目移植tinymce踩坑
转载:https://segmentfault.com/a/1190000012791569?utm_source=tag-newest 2019-2-18 貌似这篇文章帮了大家一些小忙最近tinym ...
- java设计模式自我总结---代理模式
代理模式是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用,通俗的来讲代理模式就是我们生活中常见的中介. Spring 的AOP面向切面就是使用动态代理模式来实现的: 打个比方说:我要买房 ...
- django第一天
今天是双十一跑了个1000很累. django 终于学到了,学了这么多天,乱七八糟的东西. 今天只是学了初级的配置文件和响应请求. 配置CSS和JS 文件目录 配置html文件目录 响应请求 配置路径 ...
- 连接慢的主要原因是DNS解析导致
连接慢的主要原因是DNS解析导致解决方法: 1.在ssh服务端上更改/etc/ssh/sshd_config文件中的配置为如下内容:UseDNS no# GSSAPI optionsGSSAPIAut ...
- 参数ref与out
通常我们向方法中传递的是值,方法获得的是这些值的一个拷贝,然后使用这些拷贝,当方法运行完毕后,这些拷贝将被丢弃,而原来的值不会受到影响. 这种情况是通常的,当然还有另外一种情况,我们向方法传递参数的形 ...
- ajax的xmlHttpRequest异步请求和Springmvc的sendRedirect失效问题
参考: Ext 提交表单用的异步提交Ajax.Ajax在发送请求时后台返回的数据(json或者html页面)在其回调函数中处理. 你这个相当于后台把Center_right.jsp页面已经返回给前台 ...
- 机器学习入门之python实现图片简单分类
小任务:实现图片分类 1.图片素材 python批量压缩jpg图片: PIL库 resize http://blog.csdn.net/u012234115/article/details/50248 ...
- Linux下PHP扩展pdo_mysql
1.进入PHP源码包ext/pdo目录 cd ext/pdo 2.执行/usr/local/php/bin/phpize[假设PHP的安装目录为/usr/local/php] /usr/local/p ...