[记录]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()

  

原文地址:https://www.cnblogs.com/wsjhk/p/10124416.html

时间: 2024-10-07 02:22:47

[记录]python异步编程async/await实现的相关文章

异步编程Async/await关键字

异步编程Async \await 关键字在各编程语言中的发展(出现)纪实. 时间 语言版本 2012.08.15 C#5.0(VS2012) 2015.09.13 Python 3.5 2016.03 ECMAScript 2016 (ES7) C#中的用法和浅层次原理 我是占位代理 Python中的用法,和协程 我是占位代理 Javascript中的说明 我是占位代理,不懂具体用法.

.net 异步编程async & await关键字的思考

C# 5.0引入了两个关键字 async和await,这两个关键字在很大程度上帮助我们简化了异步编程的实现代码,而且TPL中的task与async和await有很大的关系 思考了一下异步编程中的async & await关键字,对两个关键字尤其是await关键字一直很迷糊,因此深入思考了一下.首先借助的示例是:[你必须知道的异步编程]C# 5.0 新特性--Async和Await使异步编程更简单这是博客园一个大牛写的,自己也一直关注这个大神,不得不说,博客园大神很多,而且氛围也很好.我引入了其中

[C#] 谈谈异步编程async await

为什么需要异步,异步对可能起阻止作用的活动(例如,应用程序访问 Web 时)至关重要. 对 Web 资源的访问有时很慢或会延迟. 如果此类活动在同步过程中受阻,则整个应用程序必须等待. 在异步过程中,应用程序可继续执行不依赖 Web 资源的其他工作,直至潜在阻止任务完成. 本节将一步一步带领大家理解async和await. 期间会有 Hello World,原理介绍,异步会提高程序的运行速度吗,async和await,MVC中的异步Action,以及线程中常涉及到的线程安全和信号量,以及微软提供

异步编程async/await

什么是异步? 在异步程序中,程序代码不需要按照编写时的顺序严格执行,有时需要一在一个新的线程中运行一部分代码,有时无需创建新的 线程,但是为了更好的利用单个线程的能力,需要改变代码的执行顺序. 进程 启动程序时,系统会在内存中创建一个新的进程.进程是构成运行程序的资源的集合,这些资源包括虚地址空间.文件句柄和许多其他程序运行所需的东西. 线程 在进程内部,系统创建一个称为线程的内核对象,它代表了真正执行的程序.线程是执行线程的简称.一旦线程建立,系统会在Main方法的第一句开始线程的执行. 线程

c#异步编程async await

可以代替协程了 但是需要.net4 版本 unity2017以上版本可以用了 再也可以不用蛋疼的没有返回值的协程了 //异步编程,和Task一起用 async void TestAsync(){ //等待2秒 await Task.Delay(2000); int a = 0; while (a < 20) { //空等待 await Task.Yield();//相当于 yield return null a++; print(a); } print("haha"); } 原文

JavaScript异步编程——Async/Await vs Promise

兼容性 提醒一下各位,Node 现在从版本 7.6 开始就支持 async/await 了.而就在前几天,Node 8已经正式发布了,你可以放心地使用它. 如果你还没有试过它,这里有一堆带有示例的理由来说明为什么你应该马上采用它,并且再也不会回头. Async/await  对于那些从未听说过这个话题的人来说,如下是一个简单的介绍: Async/await 是一种编写异步代码的新方法.之前异步代码的方案是回调和 promise. Async/await 实际上是建立在 promise 的基础上.

&lt;史上最强&gt;深入理解 Python 异步编程(上)

前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知道如何使用 Tornado.Twisted.Gevent 这类异步框架上,出现各种古怪的问题难以解决.而且使用了异步框架的部分同学,由于用法不对,感觉它并没牛逼到哪里去,所以很多同学做 Web 后端服务时还是采用 Flask.Django等传统的非异步框架. 从上两届 PyCon 技术大会看来,异步编程已经成了 Python 生态下一阶段的主旋律.如新兴的 Go.Rust.

深入理解 Python 异步编程(上)

http://python.jobbole.com/88291/ 前言 很多朋友对异步编程都处于"听说很强大"的认知状态.鲜有在生产项目中使用它.而使用它的同学,则大多数都停留在知道如何使用 Tornado.Twisted.Gevent 这类异步框架上,出现各种古怪的问题难以解决.而且使用了异步框架的部分同学,由于用法不对,感觉它并没牛逼到哪里去,所以很多同学做 Web 后端服务时还是采用 Flask.Django等传统的非异步框架. 从上两届 PyCon 技术大会看来,异步编程已经成

这篇文章讲得精彩-深入理解 Python 异步编程(上)!

可惜,二和三现在还没有出来~ ~~~~~~~~~~~~~~~~~~~~~~~~~ http://python.jobbole.com/88291/ ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 在Python 3.3 引入yield from新语法之后,就不再推荐用yield去做协程.全都使用yield from由于其双向通道的功能,可以让我们在协程间随心所欲地传递数据. 4.5.3 yield from改进协程总结 用yield from改进基于生成器的协程,代码抽象程度更高.使业务