前言:
而今同学们对“python 进程池阻塞和非阻塞”大体比较重视,看官们都想要了解一些“python 进程池阻塞和非阻塞”的相关资讯。那么小编同时在网摘上汇集了一些关于“python 进程池阻塞和非阻塞””的相关内容,希望兄弟们能喜欢,各位老铁们一起来学习一下吧!在Web服务中使用线程池加速
1、Web服务的架构以及特点
Web后台服务的特点:
1、Web服务对响应时间要求非常高,比如要求200MS返回
2、Web服务有大量的依赖IO操作的调用,比如磁盘文件、数据库、远程API
3、Web服务经常需要处理几万人、几百万人的同时请求
2、使用线程池ThreadPoolExecutor加速
使用线程池ThreadPoolExecutor的好处:
1、方便的将磁盘文件、数据库、远程API的IO调用并发执行
2、线程池的线程数目不会无限创建(导致系统挂掉),具有防御功能
使用多进程multiprocessing加速程序的运行
1、有了多线程threading,为什么还要用多进程multiprocessing
如果遇到了CPU密集型计算,多线程反而会降低执行速度!
虽然有全局解释器锁GIL,但是因为有IO的存在多线程依然可以加速运行。
CPU密集型计算,线程的自动切换反而变成了负担,多线程甚至减慢了运行速度。
multiprocessing模块就是python为了解决GIL缺陷引入的一个模块,原理是用多进程在多CPU上并行执行。
2、多进程multiprocessing知识梳理(对比多线程threading)
3、代码实战:单线程、多线程、多进程对比CPU密集计算速度
CPU密集型计算:100次“判断大数字是否是素数”的计算
由于GIL的存在,多线程比单线程计算的还慢,而多进程可以明显加快执行速度
Python异步IO实现并发爬虫
单线程爬虫的执行路径
协程:在单线程内实现并发
用一个超级循环(其实就是while true)循环配合IO多路复用原理(IO时CPU可以干其他事情)
Python 异步IO库介绍:asyncio
import asyncio# 获取事件循环loop = asyncio.get_event_loop()# 定义协程async def myfunc(url): await get_url(url)# 创建task列表tasks = [loop.create_task(myfunc(url)) for url in urls]# 执行爬虫事件列表loop.run_until_complete(asyncio.wait(tasks))
注意:
异步IO编程中,依赖的库必须支持异步IO特性。requests 不支持异步,需要用 aiohttp。
自动听歌、解压缩、下载等等
使用subprocess启动电脑的子进程
subprocess 模块:
•允许你生成新的进程
•连接它们的输入、输出、错误管道
•并且获取它们的返回码
应用场景:
•每天定时8:00自动打开酷狗音乐播放歌曲
•调用7z.exe自动解压缩.7z文件
•通过Python远程提交一个torrent种子文件,用电脑启动下载
subprocess的实例
用默认的应用程序打开歌曲文件# 注:windows下是start、mac下是open、Linux是see# windows 环境需要加 shell = Trueproc = subprocess.Popen(['start', '余生一个浪.mp3'], shell=True)proc.communicate()用7z.exe解压7z压缩文件proc = subprocess.Popen([r"C:\Program Files\7-Zip\7z.exe", "x", "./datas/7z_test.7z", "-o./datas/extract_7z_test", "-aoa"], shell=True)proc.communicate()
在异步IO中使用信号量控制爬虫并发度
信号量(英语:Semaphore)
信号量(英语:Semaphore)又称为信号量、旗语
是一个同步对象,用于保持在0至指定最大值之间的一个计数值。当线程完成一次对该semaphore对象的等待(wait)时,该计数值减一;当线程完成一次对semaphore对象的释放(release)时,计数值加一。当计数值为0,则线程等待该semaphore对象不再能成功直至该semaphore对象变成signaled状态semaphore对象的计数值大于0,为signaled状态;计数值等于0,为nonsignaled状态.
方式一:
sem = asyncio.Semaphore(10)# ... laterasync with sem: # work with shared resource
方式二:
sem = asyncio.Semaphore(10)# ... laterawait sem.acquire()try: # work with shared resourcefinally: sem.release()异步库Asyncio VS 异步库Gevent
asyncio:Python3 官方异步IO库
import asyncio# 获取事件循环loop = asyncio.get_event_loop()# 定义协程async def myfunc(url): await get_url(url)# 创建task列表tasks = [loop.create_task(myfunc(url)) for url in urls]# 执行爬虫事件列表loop.run_until_complete(asyncio.wait(tasks))
注意:
asyncio 很多库都不支持
Gevent:Python 异步IO库
安装:
pip install gevent
Gevent是一个基于微线程库Greenlet的并发框架
原理:
提供猴子补丁MonkeyPatch方法,通过该方法gevent能够 修改标准库里面大部分的阻塞式系统调用,包括socket、ssl、threading和 select等模块,而变为协作式运行
异步库 asyncio 对比 gevent
Gevent:
优点:只需要monkey.patch_all(),就能自动修改阻塞为非阻塞,简单强大缺点:不知道它具体patch了哪些库修改了哪些模块、类、函数。 创造了“隐式的副作用”,如果出现问题很多时候极难调试
Asyncio:
优点:明确使用asyncio、await等关键字编程,直观易读缺点:只支持很少的异步库,比如aiohttp
总结自蚂蚁学Python笔记
标签: #python 进程池阻塞和非阻塞