1.  
  2. 主页
  3.  / 
  4. Python基础到高级
  5.  / 
  6. 异步编程
  7.  / 
  8. asyncio

asyncio

asyncio

在上一篇文章中,借“廖雪峰”大神的文章介绍了下协程,这次来说下asyncio这个模块

asyncio是Python 3.4版本引入的标准库,直接内置了对异步IO的支持。

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

在3.5以后对于协程的定义Python有了变动

3.5之前是这样定义的

In [1]: import asyncio

In [2]: @asyncio.coroutine
   ...: def sleep(x):
   ...:     yield asyncio.sleep(3)
   ...:
   
这看着是一个函数,但是其实,这个是一个生成器

3.5以后有了语言级别的支持

不使用装饰器,使用async关键字来定义协程

In [3]: async def sleep(x):
   ...:     await asyncio.sleep(x)
   ...:   

协程是必须跑在EventLoop中的

import asyncio
async def hello():
    print("Hello world!")
    # 异步调用asyncio.sleep(1):
    r = await from asyncio.sleep(1)
    print("Hello again!")

# 获取EventLoop:
loop = asyncio.get_event_loop()
# 执行coroutine
loop.run_until_complete(hello())
loop.close()    

3.5后对协程的一些支持

async with

在之前介绍上下文管理的时候提到过with方法,with方法实现了__enter__和__exit__的魔术方法,在3.5以后,Python对协程也加入了with的支持

import asyncio
import datetime
import time

class AsyncContentManager:
    async def __aenter__(self):
        print('aenter: {}'.format(datetime.datetime.now()))
    async def __aexit__(self, exc_type, exc_val, exc_tb):
        print('aexit: {}'.format(datetime.datetime.now()))

async def so():
    async with AsyncContentManager():
        time.sleep(1)
        print('body: {}'.format(datetime.datetime.now()))

loop = asyncio.get_event_loop()
loop.run_until_complete(so())
loop.run_forever()    

使用协程实现EchoServer

server端

import asyncio
async def echo_server(r,w):
    while True:
        message = await r.read(1024)
        print(message.strip())
        w.write(message)
        await w.drain()
    w.close()

loop = asyncio.get_event_loop()
server = asyncio.start_server(echo_server, host='127.0.0.1', port=9999, loop=loop)
loop.run_until_complete(server)
loop.run_forever()    

client端(直接拿自官方实例)

import asyncio

@asyncio.coroutine
def tcp_echo_client(message, loop):
    reader, writer = yield from asyncio.open_connection('127.0.0.1', 8888,
                                                        loop=loop)

    print('Send: %r' % message)
    writer.write(message.encode())

    data = yield from reader.read(100)
    print('Received: %r' % data.decode())

    print('Close the socket')
    writer.close()

message = 'Hello World!'
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(message, loop))
loop.close()
这篇文章对您有用吗?

我们要如何帮助您?

发表评论

您的电子邮箱地址不会被公开。