博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python异步IO
阅读量:6998 次
发布时间:2019-06-27

本文共 3311 字,大约阅读时间需要 11 分钟。

在IO操作的过程中,当前线程被挂起,而其他需要CPU执行的代码就无法被当前线程执行了。

我们可以使用多线程或者多进程来并发执行代码,为多个用户服务。
但是,一旦线程数量过多,CPU的时间就花在线程切换上了,真正运行代码的时间就少了,结果导致性能严重下降。
异步IO:当代码需要执行一个耗时的IO操作时,它只发出IO指令,并不等待IO结果,然后就去执行其他代码了。一段时间后,当IO返回结果时,再通知CPU进行处理。
对于大多数IO密集型的应用程序,使用异步IO将大大提升系统的多任务处理能力。

1. 异步IO

1.1 协程

协程,又称微线程,纤程。英文名Coroutine

子程序(函数)调用是通过栈实现的,一个线程就是执行一个子程序。
协程的执行过程中,在子程序内部可中断,然后转而去执行别的子程序,在适当的时候再回来接着执行。
Python对协程的支持是通过生成器实现的。
在生成器中,我们不但可以通过for循环来迭代,还可以不断调用next()函数获取由yield语句返回的下一个值。但是Pythonyield不但可以返回一个值,它还可以接收调用者发出的参数。

def consumer():    r = ''    while True:        n = yield r        if not n:            return        print('[CONSUMER] Consuming %s...' % n)        r = '200 OK'def produce(c):    c.send(None)    n = 0    while n < 5:        n = n + 1        print('[PRODUCER] Producing %s...' % n)        r = c.send(n)        print('[PRODUCER] Consumer return: %s' % r)    c.close()c = consumer()produce(c)
[PRODUCER] Producing 1...[CONSUMER] Consuming 1...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 2...[CONSUMER] Consuming 2...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 3...[CONSUMER] Consuming 3...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 4...[CONSUMER] Consuming 4...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 5...[CONSUMER] Consuming 5...[PRODUCER] Consumer return: 200 OK

1.2 asyncio

asyncio的编程模型是一个消息循环。我们从asyncio模块中直接获取一个EventLoop的引用,然后把需要执行的协程扔到EventLoop中执行,就实现了异步IO。

import asyncio@asyncio.coroutinedef hello():    print("Hello world!")    # 异步调用asyncio.sleep(1):    r = yield from asyncio.sleep(1)    print("Hello again!")# 获取EventLoop:loop = asyncio.get_event_loop()# 执行coroutineloop.run_until_complete(hello())loop.close()

@asyncio.coroutine把一个生成器标记为协程类型,然后,我们就把这个协程扔到EventLoop中执行。

import threadingimport asyncio@asyncio.coroutinedef hello():    print('Hello world! (%s)' % threading.currentThread())    yield from asyncio.sleep(1)    print('Hello again! (%s)' % threading.currentThread())loop = asyncio.get_event_loop()tasks = [hello(), hello()] # 封装两个协程loop.run_until_complete(asyncio.wait(tasks))loop.close()# Hello world! (<_MainThread(MainThread, started 9700)>)# Hello world! (<_MainThread(MainThread, started 9700)>)# Hello again! (<_MainThread(MainThread, started 9700)>)# Hello again! (<_MainThread(MainThread, started 9700)>)

1.3 async/await

import asyncioasync def hello():    print("Hello world!")    r = await asyncio.sleep(1)    print("Hello again!")        # 获取EventLoop:loop = asyncio.get_event_loop()# 执行coroutineloop.run_until_complete(hello())loop.close()

1.4 aiohttp

import asynciofrom aiohttp import webasync def index(request):    await asyncio.sleep(0.5)    return web.Response(body='

Index

'.encode('utf-8'), content_type='text/html')async def hello(request): await asyncio.sleep(0.5) text = '

hello, %s!

' % request.match_info['name'] return web.Response(body=text.encode('utf-8'), content_type='text/html')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()

1393432-20190408235304972-37886076.png

1393432-20190408235327842-1632476881.png

参考资料:

转载于:https://www.cnblogs.com/gzhjj/p/10674162.html

你可能感兴趣的文章
完整部署CentOS7.2+OpenStack+kvm 云平台环境(3)--为虚拟机指定固定ip
查看>>
BLE 广播数据解析
查看>>
Oracle用户密码过期和用户被锁解决方法【转】
查看>>
Android 解决Android的TextView和EditText换行问题
查看>>
CSS效果集锦(持续更新中)
查看>>
通过重建Hosting系统理解HTTP请求在ASP.NET Core管道中的处理流程[中]:管道如何处理请求...
查看>>
Eigen教程(9)
查看>>
单元测试
查看>>
操作hadoop的经验积累
查看>>
微信企业号验证
查看>>
请问set JAVA_OPTS的各项參数是什么意思?
查看>>
Linux安装JDK
查看>>
C#常用控件缩写
查看>>
.NET足球赛事资料数据库平台SmartLottery开源发布——全球足球联赛应有尽有
查看>>
关于Eclipse生成和导入Patch文件.
查看>>
如何使用Photoshop(PS)将图片的底色变为透明
查看>>
IDEA实现序列号接口
查看>>
人件札记:保持高效的办公室环境
查看>>
Mysql中使用流式查询避免数据量过大导致OOM
查看>>
为什么中台是传统企业数字化转型的关键?
查看>>