码迷,mamicode.com
首页 > 编程语言 > 详细

【python】异步IO

时间:2018-07-07 23:26:19      阅读:272      评论:0      收藏:0      [点我收藏+]

标签:oop   eve   outer   方法   strip()   current   多个   状态   router   

No1:

协程看上去也是子程序,但执行过程中,在子程序内部可中断,然后转而执行别的子程序,在适当的时候再返回来接着执行。

优势:

1.最大的优势就是协程极高的执行效率。因为子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。

2.不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多。

No2:

因为协程是一个线程执行,那怎么利用多核CPU呢?最简单的方法是多进程+协程,既充分利用多核,又充分发挥协程的高效率,可获得极高的性能。

Python对协程的支持是通过generator实现的。

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)

运行结果

技术分享图片

consumer函数是一个generator,把一个consumer传入produce后:

  1. 首先调用c.send(None)启动生成器;

  2. 然后,一旦生产了东西,通过c.send(n)切换到consumer执行;

  3. consumer通过yield拿到消息,处理,又通过yield把结果传回;

  4. produce拿到consumer处理的结果,继续生产下一条消息;

  5. produce决定不生产了,通过c.close()关闭consumer,整个过程结束。

整个流程无锁,由一个线程执行,produceconsumer协作完成任务,所以称为“协程”,而非线程的抢占式多任务

No3:

【asyncio】

import asyncio

async def hello():
    print("Hello world!")
    r=await asyncio.sleep(1)
    print("Hello again!")
    
loop=asyncio.get_event_loop()
loop.run_until_complete(hello())
loop.close()

运行结果

技术分享图片

import threading
import asyncio

@asyncio.coroutine
def 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()

运行结果

技术分享图片

import asyncio

@asyncio.coroutine
def wget(host):
    print(wget %s... % host)
    connect=asyncio.open_connection(host,80)
    reader,writer=yield from connect
    header=GET / HTTP/1.0\r\nHost:%s\r\n\r\n % host
    writer.write(header.encode(utf-8))
    yield from writer.drain()
    while True:
        line = yield from reader.readline()
        if line == b\r\n:
            break
        print(%s header > %s % (host,line.decode(utf-8).rstrip()))
    writer.close()
    
loop=asyncio.get_event_loop()
tasks=[wget(host) for host in [www.sina.com.cn,www.sohu.com,www.163.com]]
loop.run_until_complete(asyncio.wait(tasks))
loop.close()

运行结果

技术分享图片

No4:

异步操作需要在coroutine中通过yield from完成;

多个coroutine可以封装成一组Task然后并发执行。

No5:

asyncawait是针对coroutine的新语法,要使用新的语法,只需要做两步简单的替换:

  1. @asyncio.coroutine替换为async
  2. yield from替换为await

No6:

【aiohttp】

import asyncio

from aiohttp import web

async def index(request):
    await asyncio.sleep(0.5)
    return web.Response(body=b<h1>Index</h1>, content_type=text/html)

async def hello(request):
    await asyncio.sleep(0.5)
    text=<h1>hello,%s!</h1> % 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 srv
    
loop=asyncio.get_event_loop()
loop.run_until_complete(init(loop))
loop.run_forever()

运行结果

技术分享图片

技术分享图片

【python】异步IO

标签:oop   eve   outer   方法   strip()   current   多个   状态   router   

原文地址:https://www.cnblogs.com/anni-qianqian/p/9278286.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!