python并行编程 - 异步篇
目录1
介绍篇
线程篇
进程篇
异步篇2
GPU篇
分布式篇
介绍
除了线性
、并行
执行模式外,还有异步
模式,它与事件编程一样,十分重要
在并发的异步模式中,不同的任务在时间线上是相互交错的,而且一切都是在单一控制流(单线程)下进行的
1.asyncio (过时)
基本使用
1.1 使用asyncio实现事件循环管理
什么是事件循环?
在计算系统中,能够产生事件的实体被称为事件源(event source),而负责协商管理事件的实体被称为事件处理器(event handler)
它实现了管理计算代码中所有事件的功能:在程序执行期间事件循环不断周期反复,追踪某个数据内部发生的事件,将其纳入队列,如果主线程空闲则调用事件处理器一个一个地处理这些事件
注:事件循环不能使用@asyncio.coroutine
标为协程
示例1:
延迟3秒后执行
import asyncio
import timedef A(x):print(x)time.sleep(1) # 使用run_forever()不能用ayncio.sleep()延时loop.call_soon(B)print('c')def B():print('b')loop.stop()loop = asyncio.get_event_loop()
# loop.call_soon(A, 'a')
loop.call_later(3.0, A, 'a')
loop.run_forever()
loop.close()print('end')
输出:
a
c
b
end
在A()中再利用loop调用其它函数B()时,A也并不停下来,实现协程效果
1.2使用asyncio实现协程
什么是协程?
当程序变得冗长复杂时,将其划分成子例程的方式会使处理变得更加便利,每个子例程完成一个特定的任务
子例程无法独立运行,只能在主程序的要求下才能运行,主程序负责协调子例程的使用,协程就是子例程的泛化。在协程中,可以暂停执行点,同时保持干预时的本地状态,便于后续继续执行
协程相互交错的控制组件就是事件循环,事件循环追踪全部的协程,并安排其执行时间
协程的其它重要特点:
- 协程支持多个进入点,可以多次生成(yield)
- 协程能够执行转移至任何其它协程
生成(yield)这个术语用于描述那些暂停并将控制流传递给另一个协程的协程,协程可以同时传递控制流和值
示例2:
A()和B()类似并行
import asyncio@asyncio.coroutine
def A():print('a - start')yield from asyncio.sleep(1)print('a - end')@asyncio.coroutine
def B(x):print('b - start')result = yield from C()print(x)yield from asyncio.sleep(1)print(f'b :{result}')@asyncio.coroutine
def C():print('c - start')yield from asyncio.sleep(1)print('c - end')return 'this is C return'loop = asyncio.get_event_loop()
# loop.run_until_complete(A()) # 只执行一个
# loop.run_until_complete(asyncio.wait([A(), B('d')])) # 并发执行方法1
tasks = [asyncio.Task(A()), asyncio.Task(B('b - end'))]
loop.run_until_complete(asyncio.wait(tasks)) # 并发执行方法2
loop.close()
print('end')# 类asyncio.Task(coroutine)用于调度协程的执行
# asyncio.wait(tasks)将等待给定协程执行完毕
输出:
a - start
b - start
c - start
a - end
c - end
b - end
b :this is C return
end
分析:asyncio.sleep()
期间,主线程并未等待,而是去执行EventLoop
中可执行的coroutine
注:@asyncio.coroutine
把一个generator标记为coroutine
类型,再把这个coroutine放到EventLoop中执行(实测,可以不@标记)
相关方法
loop = get_event_loop() : 获得当前上下文的事件循环
如果close()关闭了后,重新打开需要以下操作:
loop = asyncio.new_event_loop() : 创建新的时间循环对象
asyncio.set_event_loop(loop) : 将当前上下文的时间循环设置为指定的循环
loop.call_soon(callback, *args) : 立即调用回调对象,参数
loop.call_later(delay, callback, *args) : 延时delay秒后,调用回调对象
loop.call_at(when, callback, *args) : 在指定的时间调用回调对象,(when是绝对时间,可以参考loop.time()设置)
loop.run_forever() : 一直执行,直到调用stop()
loop.run_until_complete(future) : 运行指定的协程函数(Future3)
loop.time() : 获取事件循环的内部时钟
loop.close() : 关闭事件循环
loop.is_running() : 是否运行中
loop.is_close() : 是否关闭
使用示例
示例:
异步网络并行访问
import asyncio@asyncio.coroutine
def wget(host):print('wget %s...' % host)connect = asyncio.open_connection(host, 80)reader, writer = yield from connectheader = 'GET / HTTP/1.0\r\nHost: %s\r\n\r\n' % hostwriter.write(header.encode('utf-8'))yield from writer.drain()while True:line = yield from reader.readline()if line == b'\r\n':breakprint('%s header > %s' % (host, line.decode('utf-8').rstrip()))# Ignore the body, close the socketwriter.close()loop = asyncio.get_event_loop()
tasks = [wget(host) for host in ['www.baidu.com', 'www.aliyun.com', 'www.qq.com']]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
2.async/await
2.1 客户端使用
为了简化标识异步io,python3.5引入新语法async
、await
只需将2步替换:
asyncio.coroutine
->async
yield from
->await
示例:
import asyncio@asyncio.coroutine
def A():print('a')yield from asyncio.sleep(1)print('c')loop = asyncio.get_event_loop()
tasks = [asyncio.Task(A())]
loop.run_until_complete(asyncio.wait(tasks)) # 并发执行方法2
loop.close()
print('end')
替换为:
import asyncioasync def A():print('a')await asyncio.sleep(1)print('c')loop = asyncio.get_event_loop()
tasks = [asyncio.Task(A())]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()
print('end')
2.2 服务器端使用
asyncio
可以实现单线程并发io操作,如果仅用于客户端,效果不大
可以用在服务器端,由于HTTP连接就是io操作,因此可以使用单线程+协程实现多用户的高并发
asyncio
实现了TCP、UDP、SSL等协议,aiohttp则是基于asyncio实现的HTTP框架
示例:
启动一个web服务,通过浏览器访问localhost:8000
import asynciofrom aiohttp import webasync def index(request):await asyncio.sleep(0.5)return web.Response(body='<h1>Index</h1>')async def hello(request):await asyncio.sleep(0.5)text = '<h1>hello, %s!</h1>' % request.match_info['name']return web.Response(body=text)async def init(loop):app = web.Application(loop=loop)app.router.add_route('GET', '/', index)app.router.add_route('GET', '/hello/{name}', hello)srv = await loop.create_server(app.make_handler(), '127.0.0.1', 8000)print('Server started at http://127.0.0.1:8000...')return srvloop = asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()
参考书籍:《Python并行编程手册》 ↩︎
这篇主要参考:廖雪峰 - asyncio:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/00143208573480558080fa77514407cb23834c78c6c7309000 ↩︎
Future:是Asyncio的一个类,与concurrent.futures.Futures非常相似,Futures类代表一个还不可用的结果,它是对尚未完成的任务的抽象表示;Python 3.2引入concurrent.futures模块,支持管理并发编程任务,如进程池和线程池、非确定性执行流、多进程、线程同步(这个目前没看出有什么特别的,池化管理不是多线程和多进程库自带吗?concurrent.futures.ProcessPoolExecutor) ↩︎
python并行编程 - 异步篇相关推荐
- Python并发编程理论篇
Python并发编程理论篇 前言 很多人学习python,不知道从何学起. 很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手. 很多已经做案例的人,却不知道如何去学习更加高深的知识 ...
- Python 并行编程教程 | Lynda教程 中文字幕
Python 并行编程教程 | Lynda教程 中文字幕 Python Parallel Programming Solutions 课程ID: 604237 时长: 4.0小时 所属类别:Pytho ...
- Python 并行编程
参考:python-parallel-programming-cookbook-cn:https://python-parallel-programmning-cookbook.readthedocs ...
- python中的多线程求值串行和并行_python多线程和多进程——python并行编程实验
工作中经常涉及到加速程序的运行,除了代码逻辑的优化,算法的优化之外,还经常使用的一招就是并发编程.至于python的并型编程这一块.说到并行编程,我们不得不谈线程和进程这两个概念: + 进程:对于操作 ...
- python多线程和多进程——python并行编程实验
工作中经常涉及到加速程序的运行,除了代码逻辑的优化,算法的优化之外,还经常使用的一招就是并发编程.至于python的并型编程这一块.说到并行编程,我们不得不谈线程和进程这两个概念: 进程:对于操作系统 ...
- python多线程并行编程,Python并行编程(二):基于线程的并行
1.介绍 软件应用中使用最广泛的并行编程范例是多线程.通常一个应用有一个进程,分成多个独立的线程,并行运行.互相配合,执行不同类型的任务. 线程是独立的处理流程,可以和系统的其他线程并行或并发地执行. ...
- Python少儿编程入门篇(2)算术运算和赋值运算
Python少儿编程小课堂(二) 入门篇(2)算术运算和赋值运算 标识符 就是一个名字,就好像我们每个人都有自己的名字一样,主要作用就给变量.函数.类.模块以及其他对象起名字. 命名规则 1. 标识符 ...
- Python少儿编程入门篇(3)比较运算和逻辑运算
Python少儿编程小课堂(三) 入门篇(3)比较运算和逻辑运算 运算符(2) 上一节课讲了算术运算符和赋值运算符,本节继续讲其它运算符: 比较运算符 ==.!=.>.<.>= .& ...
- python并行编程篇
章节目录 第二十一章 进程对象 进程的理解 操作系统 OS发展史 第二十二章 进程并发 进程并发的原理 进程并发编程实践 僵尸进程与孤儿进程(linux系统) 守护进程 互斥锁 IPC机制(进程间的通 ...
- C#的变迁史08 - C# 5.0 之并行编程总结篇
C# 5.0 搭载于.NET 4.5和VS2012之上. 同步操作既简单又方便,我们平时都用它.但是对于某些情况,使用同步代码会严重影响程序的可响应性,通常来说就是影响程序性能.这些情况下,我们通常是 ...
最新文章
- 不会真有人国庆都不打王者吧?
- Docker的安装和使用说明——Docker for Windows
- cp: omitting directory”错误
- 动机模型_解读冰山模型:强烈的动机是成功的开始
- 查看运行时间_怎样查看自己电脑系统的版本信息?
- SpriteKit在复制节点时留了一个巨坑给开发者,需要开发者手动把复制节点的isPaused设置为false...
- SCCM2012软件更新(WSUS补丁)同步成功无法获取补丁问题
- python读取mysql以html形式输出_python从mysql数据库提取出来的数据怎么在html里显示...
- 数据库备分复制到另一台机器
- android混合编程 pdf,混合编程在A/D转换中的应用.pdf
- html5怎么设置黑色背景及亮度,网页背景怎么设置为纯黑色css样式
- 【机器学习】二次规划
- Scratch(四):万圣节南瓜点灯
- 倒立摆状态反馈控制——分析、建模与仿真(matlab)
- 8个微信小程序UI组件框架
- VM虚拟机安装及安装Windows系统
- PSO(粒子群算法)MATLAB仿真完整代码
- RK3566,ES7202声卡驱动添加
- 信息大爆炸时代的生存指南(2):我们的基本信息素养
- 对win10突然卡顿的一种情况的记录
热门文章
- 为什么计算机关机后自动开机,为何我家的电脑关机后又自动开机?
- 编写一个Linux虚拟网卡来实现类NVI
- 【python】OpenCV—RGB, Rectangle, Circle, SS(1)
- DEV C++ 解决方案
- 小小屋影视全网搜索在线播放工具
- python 头条视频_今日头条python视频消重赞
- 中国移动H1S-3光猫破解路由器桥接教程
- 不到3000块钱,如何支撑起每月500万次访问量及80TB流量的网站?
- 项目审查图片报404找不到
- mysql数据库查询优化技术 视频教程_炼数成金MySql视频教程 MySQL数据库查询优化技术 15周课程深入学习MySQL数据库查询...