如何在Python中真正实现超时?

4
如何在Python中实现真正的超时?代码如下: http://eventlet.net/doc/modules/timeout.html
#!/usr/bin/python
import eventlet
import time
import sys
import random

while True:
        try:
         with eventlet.timeout.Timeout(1, False):
                print 'limited by timeout execution'
                while True:
                        print '\r' + str(random.random()),
                        sys.stdout.flush()
                        eventlet.sleep(0)
                print ' Never printed Secret! '
        except Exception as e:
                print ' Exception: ', e
        finally:
                print ''
                print ' Timeout reached '
                print ''

超时永远不会到达。我错在哪里了吗?
P.s. 我替换了:
 time.sleep(0.1)

使用:

 eventlet.sleep(0)

将 False 添加到异常中,现在它可以正常工作:

with eventlet.timeout.Timeout(1):

change to:

with eventlet.timeout.Timeout(1, False):

但是它只能与eventlet.sleep(0.1)一起使用。

例如,以下代码是错误的:

#!/usr/bin/python
import eventlet
import time
start_time = time.time()
data = 0
with eventlet.timeout.Timeout(1, False):
        while True:
                data +=1
print 'Catch data ', data, ' in ', time.time() - start_time

我只是添加了0秒的延迟:

我只是添加了0秒的延迟:

eventlet.sleep(0)

它的工作效果非常好。

已解决

1个回答

5

eventlet的超时功能并不像你想象中的那样神奇。它只能检测“绿色线程”代码中的超时 - 也就是使用eventlet协作多线程系统的代码。正如在超时文档中所指出的,“无法使用此类对仅涉及CPU操作的操作设置超时”。time.sleep会暂停Python的内部线程系统,而不是eventlet的绿色线程。

相反,请使用eventlet.sleep,它可以与绿色线程正确地配合使用。


2
如果您阅读Timeout文档,您会发现它的行为与预期完全一致:如果超时在块完成之前到期,Timeout会将自己作为异常抛出。您可以在文档中找到如何捕获Timeout的示例。正如预期的那样,在异常结束程序之前,finally块会运行。 - kevingessner
非常感谢,我将这一行代码:with eventlet.timeout.Timeout(1): 改为了 with eventlet.timeout.Timeout(1, False):,崩溃问题得到了解决。 - stackterminator
看起来 eventlet 抛出了自己的异常。 - stackterminator
向上!向上!为什么不睡觉就不能工作?我把代码放在底部,还有一个问题。 - stackterminator
1
因为你没有给eventlet运行的机会。你可能会发现这个答案有用:http://stackoverflow.com/posts/14227272/revisions - temoto
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接