程序挂起asyncio

Sza*_*mbi 2 python python-asyncio python-3.5

这是我的代码:

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()
Run Code Online (Sandbox Code Playgroud)

这是输出:

b'HELLO'
Run Code Online (Sandbox Code Playgroud)

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

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

bag*_*rat 5

问题是语法和API定义的组合.

首先,请参阅文档add_reader,其中指出它需要回调.从单词本身来看并不明显,但通过说回调它意味着常规功能.

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

  • @DombiSzabolcs查看[asyncio文档中的UDP示例](https://docs.python.org/3/library/asyncio-protocol.html#udp-echo-server-protocol)和[循环. create_datagram_endpoint method](https://docs.python.org/3/library/asyncio-eventloop.html#asyncio.AbstractEventLoop.create_datagram_endpoint) (2认同)