如何使协程停止超时?
我不明白为什么asynchtml" target="_blank">io.wait_for()对我不起作用。我有这样的一段代码(计划实现telnet客户端的实现):
def expect(self, pattern, timeout=20):
if type(pattern) == str:
pattern = pattern.encode('ascii', 'ignore')
return self.loop.run_until_complete(asyncio.wait_for(self.asyncxpect(pattern), timeout))
async def asyncxpect(self, pattern): #receives data in a cumulative way until match is found
regexp = re.compile(b'(?P<payload>[\s\S]*)(?P<pattern>%s)' %pattern)
self.buffer = b''
while True:
# add timeout
# add exception handling for unexpectedly closed connections
data = await self.loop.sock_recv(self.sock, 10000)
self.buffer += data
m = re.match(regexp, self.buffer)
if m:
payload = m.group('payload')
match = m.group('pattern')
return payload, match
正如我认为的那样,在某些时候(在await语句中)将控制返回到事件循环。我认为应该在没有更多数据要接收时发生。如果事件循环具有控制权,则它可以随着超时而停止。
但是,如果服务器没有发送任何有用的信息(匹配的信息),我的代码就会在此循环中迷路,就在等待点。
我认为这与Python异步强制超时这个问题不同,因为我没有使用诸如time.sleep(n)之类的阻塞语句。
这是我的代码
服务器关闭连接时,sock_recv
返回一个空的字节数组(b''
),表示文件结束。由于您不处理该条件,因此您的代码最终陷入了处理相同缓冲区的无限循环中。
要更正它,请添加以下内容:
if data == b'':
break
…data = await loop.sock_recv(...)
行后
但是上面仍然没有解释为什么wait_for
不能取消无赖协程。问题是await
,正如有时可以理解的那样,这并不意味着“将控制传递给事件循环”。它的意思是“从提供的等待对象中请求值,
如果 (并且只要)对象指示它没有准备好值,就将控制权交给事件循环。” 该 如果 是至关重要的:如果对象 确实
已经准备好时,首先询问,该值将被立即使用而不用推迟事件循环的值。换句话说,await
不能保证事件循环有运行的机会。
例如,下面的协程完全阻塞事件循环和防止以往任何时候都在运行,尽管它的内环由没有任何其他的协程 ,但 等待:
async def busy_loop():
while True:
await noop()
async def noop():
pass
在您的示例中,由于套接字在文件结束时根本不会阻塞,因此协程永远不会挂起,并且(与上述错误共同作用)协程永远不会退出。
为了确保其他任务有运行的机会,您可以添加await asyncio.sleep(0)
一个循环。对于大多数代码而言,这不是必需的,因为在这些情况下,请求IO数据将很快导致等待,这时将触发事件循环。(实际上,经常需要这样做表明存在设计缺陷。)仅与EOF处理错误结合在一起,使代码卡住。
问题内容: 是否有任何参数或选项可为Python的subprocess.Popen方法设置超时? 像这样: ? 问题答案: 我会建议采取看看类中的模块。我用它来实现超时。 首先,创建一个回调: 然后打开过程: 然后创建一个计时器,该计时器将调用回调,并将过程传递给它。 在程序后面的某个位置,您可能需要添加以下行: 否则,python程序将继续运行,直到计时器运行完毕。 编辑:我被告知, 在和条件之
问题内容: 基于生成器的协程具有一种方法,该方法允许调用方和被调用方之间进行双向通信,并从调用方恢复生成的生成协程。这是将生成器变成协程的功能。 尽管新的本机协程为异步I / O提供了出色的支持,但我看不出如何获得与之等效的协程。明确禁止使用in函数,因此本机协程只能使用一条语句返回一次。尽管表达式将新值带入协程中,但这些值来自被调用方,而不是调用方,并且等待的调用从每次开始就进行评估,而不是从中
超时控制 使用 Bolt 协议进行通信的时候,SOFARPC 的超时时间默认为 3 秒,用户可以在引用服务的时候去设置超时时间,又分别可以在服务以及方法的维度设置超时时间,SOFARPC 的超时时间的设置的单位都为毫秒。 服务维度 如果需要在发布服务的时候在服务维度设置超时时间,设置对应的 timeout 参数到对应的值即可。 XML 方式 如果使用 XML 的方式引用服务,设置 <sofa:bi
问题内容: 我正在python中使用subprocess模块运行一些shell脚本。如果shell脚本运行时间很长,我想杀死该子进程。我认为如果将其传递给我的陈述就足够了。 这是代码: 我已经用一些运行120秒的shell脚本测试了此调用。我期望子进程在30秒后被杀死,但是实际上该进程正在完成120秒脚本,然后引发了Timeout Exception。现在的问题是如何通过超时杀死子进程? 问题
与子程序(或者说函数)一样,协程(coroutine)也是一种程序组件。Donald Knuth 曾说,子程序是协程的特例。 一个子程序就是一次函数调用,它只有一个入口,一次返回,调用顺序是明确的。但协程的调用和子程序则大不一样,协程允许有多个入口对程序进行中断、继续执行等操作。 Python2 可以通过 yield 来实现基本的协程,但不够强大,第三方库 gevent 对协程提供了强大的支持。另
我正在尝试解决一个来自HackerRank的问题,当我提交我的解决方案时,我得到一个错误,说明“由于超时而终止”。 问题:对n个大小的数组的左旋转操作将数组的每个元素向左移动1个单位。例如,如果对数组[1,2,3,4,5]执行两次左旋转,那么该数组将变为[3,4,5,1,2]。 给定一个由n个整数和一个数字d组成的数组,对该数组执行d个左旋转。然后将更新后的数组打印为单行以空格分隔的整数。 输入格