程序挂起asyncio

时间:2016-09-13 10:52:31

标签: python python-3.5 python-asyncio

这是我的代码:

import asyncio, socket

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind(('', 1234))
sock.setblocking(False)

queue = asyncio.Queue()

def sock_reader():
    print(sock.recv(1024))
    # x = yield from queue

def test_sock_reader():
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    sock.sendto(b'HELLO', ('127.0.0.1', 1234))

loop = asyncio.get_event_loop()
loop.add_reader(sock, sock_reader)
loop.call_later(0.5, test_sock_reader)
loop.run_forever()
loop.close()

这是输出:

b'HELLO'
  

取消注释行# x = yield from queue时,程序不再打印b'Hello'

为什么yield from会影响已经执行的命令?

1 个答案:

答案 0 :(得分:5)

问题是语法和API定义的结合。

首先,请参阅documentation of add_reader,其中指出它需要回调。从单词本身来看并不明显,但是通过说回调它意味着一个常规函数。

现在,当您取消注释# x = yield from queue行时,由于sock_reader,您的yield from函数实际上变为生成器/协同程序,在这种情况下,当调用为常规函数时(即{{ 1}}),它返回一个生成器对象,并且不会被执行。