我有一个用 socket(AF_INET, SOCK_DGRAM)
创建的套接字对象,我将在asyncio循环中使用它 . 但是我在https://docs.python.org/3/library/asyncio-eventloop.html#low-level-socket-operations找不到 sendto
函数 .
我可以安全地假设此函数是一个非阻塞系统调用,可以在asyncio循环中调用吗?或者我应该提交它以使用 run_in_executor
在另一个线程中运行?
** Documentation表示它执行系统调用,这使我担心它可能会阻塞整个循环 .
2 回答
不,你不能指望
socket.sendto
是无阻塞的 .相反,使用DatagramTransport.sendto:
数据报传输由loop.create_datagram_endpoint协程返回:
编辑 - 关于您的评论:
不,不是,
transport.sendto
使用loop.add_writer
使操作无阻塞 . 见implementation .较低级别的asyncio基于回调,而asyncio不为UDP提供基于协程的对象 . 但是,我写了module that provides high-level UDP endpoints for asyncio .
用法:
输出:
sendto()
是非阻塞的,如果writer当前不可用,则可能会引发(BlockingIOError
,InterruptedError
) .socket.sendto()
和transport.sendto()
之间的区别在于transport.sendto()
将首先尝试调用socket.sendto()
,或者等到套接字准备好用loop.add_writer()
写入,如果第一次尝试失败则再次调用socket.sendto()
.这是我从Python 3.5.2的asyncio模块的源代码中观察到的(Windows 32位)
编辑:
在Windows中,套接字操作阻止行为由
socket.settimeout
指定,因此请确保将超时值设置为0
,以便其操作不会阻止 .