我有两个greenlets。第一个greenlet在启动HTTP请求之前启动7秒超时,我知道这将需要5秒才能完成。第二个greenlet正在执行一些CPU绑定任务(由time.sleep
模拟),需要10秒才能完成。代码:
from gevent import monkey; monkey.patch_socket()
import time
import gevent
import requests
def f1():
try:
with gevent.Timeout(7):
print "f1: downloading our page in 5 seconds"
requests.get('http://httpbin.org/delay/5')
except gevent.Timeout:
print "Timed out."
else:
print "Finished!"
def f2():
print "f2: being greedy for 10 seconds"
time.sleep(10)
if __name__ == '__main__':
g1 = gevent.spawn(f1)
g2 = gevent.spawn(f2)
gevent.joinall([g1, g2])
当我运行此代码时,即使我知道HTTP请求已完成,也会触发超时:
$ python test.py
f1: downloading our page in 5 seconds
f2: being greedy for 10 seconds
Timed out.
time.sleep
电话显然是导致超时的原因,但我实际上并不关心这需要多长时间。我真正想要限制的是HTTP请求的持续时间。
是否有任何方法可以编写此代码,以便仅在未执行HTTP请求时才会发生超时?有没有办法在超时事件之前首先处理I / O事件?
答案 0 :(得分:0)
NB - 阻止调用 - 如CPU绑定函数 - 不应该分配给greenlet,因为根据定义它们会阻止所有其他greenlet运行。
使用gevent.threadpool.ThreadPool
提供的本地线程池的组合来阻止任务,使用greenlet来组合非阻塞任务。
示例代码中的行为是因为代码没有修补时间而time.sleep(10)
导致gevent超时,因为它阻塞了整个事件循环,这意味着所有的greenlets。
这可以按预期工作:
from gevent import monkey
monkey.patch_all()
import time
import gevent
import requests
def f1():
try:
with gevent.Timeout(7):
print "f1: downloading our page in 5 seconds"
requests.get('http://httpbin.org/delay/5')
except gevent.Timeout:
print "Timed out."
else:
print "Finished!"
def f2():
print "f2: being greedy for 10 seconds"
time.sleep(10)
if __name__ == '__main__':
g1 = gevent.spawn(f1)
g2 = gevent.spawn(f2)
gevent.joinall([g1, g2])
输出:
f1: downloading our page in 5 seconds
f2: being greedy for 10 seconds
Finished!
还可以使用gevent.sleep
来避免修补时间。