[记录]python异步编程async/await实现
from selectors import DefaultSelector, EVENT_READ, EVENT_WRITE
import socket
from types import coroutine
from urllib.parse import urlparse @coroutine
def until_readable(fileobj):
yield fileobj, EVENT_READ @coroutine
def until_writable(fileobj):
yield fileobj, EVENT_WRITE async def connect(sock, address):
try:
sock.connect(address)
except BlockingIOError:
await until_writable(sock) async def recv(fileobj):
result = b''
while True:
try:
data = fileobj.recv(4096)
if not data:
return result
result += data
except BlockingIOError:
await until_readable(fileobj) async def send(fileobj, data):
while data:
try:
sent_bytes = fileobj.send(data)
data = data[sent_bytes:]
except BlockingIOError:
await until_writable(fileobj) async def fetch_url(url):
parsed_url = urlparse(url)
if parsed_url.port is None:
port = 443 if parsed_url.scheme == 'https' else 80
else:
port = parsed_url.port with socket.socket() as sock:
sock.setblocking(0)
await connect(sock, (parsed_url.hostname, port))
path = parsed_url.path if parsed_url.path else '/'
path_with_query = '{}?{}'.format(path, parsed_url.query) if parsed_url.query else path
await send(sock, 'GET {} HTTP/1.1\r\nHost: {}\r\nConnection: Close\r\n\r\n'.format(path_with_query, parsed_url.netloc).encode())
content = await recv(sock)
print('{}: {}'.format(url, content)) def main():
urls = ['http://www.baidu.com/s?wd={}'.format(i) for i in range(10)]
tasks = [fetch_url(url) for url in urls] # 将任务定义成协程对象 with DefaultSelector() as selector:
while tasks or selector.get_map(): # 有要做的任务,或者有等待的 IO 事件
events = selector.select(0 if tasks else 1) # 如果有要做的任务,立刻获得当前已就绪的 IO 事件,否则最多等待 1 秒
for key, event in events:
task = key.data
tasks.append(task) # IO 事件已就绪,可以执行新 task 了
selector.unregister(key.fileobj) # 取消注册,避免重复执行 for task in tasks:
try:
fileobj, event = task.send(None) # 开始或继续执行 task
except StopIteration:
pass
else:
selector.register(fileobj, event, task) # task 还未执行完,需要等待 IO,将 task 注册为 key.data tasks.clear() main()
[记录]python异步编程async/await实现的更多相关文章
- 异步编程Async/await关键字
异步编程Async \await 关键字在各编程语言中的发展(出现)纪实. 时间 语言版本 2012.08.15 C#5.0(VS2012) 2015.09.13 Python 3.5 2016.03 ...
- 抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext
长话短说,本文带大家抓住异步编程async/await语法糖的牛鼻子: SynchronizationContext 引言 C#异步编程语法糖async/await,使开发者很容易就能编写异步代码. ...
- 温故知新,CSharp遇见异步编程(Async/Await),聊聊异步编程最佳做法
什么是异步编程(Async/Await) Async/Await本质上是通过编译器实现的语法糖,它让我们能够轻松的写出简洁.易懂.易维护的异步代码. Async/Await是C# 5引入的关键字,用以 ...
- javascript异步编程 Async/await
Async/await Async/await 在学习他之前应当补充一定的 promise 知识 它是一种与 promise 相配合的特殊语法,目前被认为是异步编程的终级解决方案 值得我们每一个人学习 ...
- [C#] 谈谈异步编程async await
为什么需要异步,异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要. 对 Web 资源的访问有时很慢或会延迟. 如果此类活动在同步过程中受阻,则整个应用程序必须等待. 在异步过程中, ...
- .net 异步编程async & await关键字的思考
C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的asy ...
- 异步编程async/await
什么是异步? 在异步程序中,程序代码不需要按照编写时的顺序严格执行,有时需要一在一个新的线程中运行一部分代码,有时无需创建新的 线程,但是为了更好的利用单个线程的能力,需要改变代码的执行顺序. 进程 ...
- c#异步编程async await
可以代替协程了 但是需要.net4 版本 unity2017以上版本可以用了 再也可以不用蛋疼的没有返回值的协程了 //异步编程,和Task一起用 async void TestAsync(){ // ...
- .NetCore 异步编程 - async/await
前言: 这段时间开始用.netcore做公司项目,发现前辈搭的框架通篇运用了异步编程方式,也就是async/await方式,作为一个刚接触的小白,自然不太明白其中原理,最重要的是,这个玩意如果不明白基 ...
随机推荐
- Windows 10预装应用太多?一个命令删除!
Windows 10预装了很多应用软件,虽然有些其实也不难用,但是使用率可能比较低,很多人也不喜欢预装的东西,而且还占空间,那么这些预装的如何彻底清除呢? 其实微软是自带了命令可以执行这样的操作,用它 ...
- Linux使用技巧:linux下将命令值赋给shell变量
很多小伙伴在写shell脚本的时候需要把命令输出的值赋给一些变量,使得脚本在运行过程中能够顺利使用这些变量.例如:很多时候我们就需要获取当前目录的绝对路径,pwd这个命令大家在熟悉不过,可是要把这个命 ...
- CrashRpt_v.1.4.2_vs2008_also_ok
1.windows多线程程序release版崩溃记录工具,便于该如何查找错误. 2.此工具主要用来配置windbug工具,一种排查程序发布版本崩溃这种非常难处理的缺陷的方法,非常棒,amazing! ...
- poi 操作Excel 以及大数据量导出
maven 依赖 (版本必须一致,否则使用SXSSFworkbook 时程序会报错) <dependency> <groupId>org.apache.poi</grou ...
- Oracle expdp/impdp 使用示例
1. 创建目录 使用数据泵之前,需要创建一个存放文件的目录. 这个目录要写入Oracle的数据字典中才能识别. (1)先查看一下已经存在的目录: SQL> col owner format a5 ...
- 07 jQuery的位置信息
一.宽度和高度 获取宽度 .width() 描述:为匹配的元素集合中获取第一个元素的当前计算宽度值.这个方法不接受任何参数..css(width) 和 .width()之间的区别是后者返回一个没有单位 ...
- Unity Shader 玻璃效果
一个玻璃效果主要分为两个部分,一部分是折射效果的计算,另一部分则是反射.下面分类进行讨论: 折射: 1.利用Grass Pass对当前屏幕的渲染图像进行采样 2.得到法线贴图对折射的影响 3.对采集的 ...
- Go语言之从0到1实现一个简单的Redis连接池
Go语言之从0到1实现一个简单的Redis连接池 前言 最近学习了一些Go语言开发相关内容,但是苦于手头没有可以练手的项目,学的时候理解不清楚,学过容易忘. 结合之前组内分享时学到的Redis相关知识 ...
- Kafka —— 基于 ZooKeeper 搭建 Kafka 高可用集群
一.Zookeeper集群搭建 为保证集群高可用,Zookeeper集群的节点数最好是奇数,最少有三个节点,所以这里搭建一个三个节点的集群. 1.1 下载 & 解压 下载对应版本Zookeep ...
- 图片加载时间缓慢问题API
一.背景 最近段时间,开发写值工具项目中,出现图片加载问题API,响应时间缓慢:为了优化图片加载问题,我进行图片压缩方法,然后API的图片加载还是慢,最终在自己无意中乱写找到了根本的原因. ...