EventLoop.sock_accept()的优雅中断

时间:2016-10-11 21:23:27

标签: python sockets python-asyncio

考虑以下代码,如何在listen()中停止执行?似乎在sock.close()被调用后挂起。没有例外提出

#!/usr/bin/env python3.5

import asyncio, socket

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('localhost', 8080))
sock.listen()
sock.setblocking(0)

async def listen():
    print('listen')
    try:
        while True:
            await asyncio.get_event_loop().sock_accept(sock)
            print('accepted')
    except:
        print('exc')

async def stop():
    await asyncio.sleep(1)
    sock.close()
    print('stopped')


asyncio.ensure_future(listen())
asyncio.ensure_future(stop())
asyncio.get_event_loop().run_forever()

1 个答案:

答案 0 :(得分:1)

使用loop.remove_reader关闭套接字或删除文件描述符不会通知loop.sock_accept

要么明确取消它:

# Listening
accept_future = asyncio.ensure_future(loop.sock_accept(sock))
await accept_future
[...]
# Closing
loop.remove_reader(sock.fileno())
sock.close()
accept_future.cancel()

或使用更高级别的协同程序,例如loop.create_serverasyncio.start_server

# Using a protocol factory
server = await loop.create_server(protocol_factory, sock=sock) 
# Using callback and streams
server = await asyncio.start_server(callback, sock=sock)