我试图了解如何实现gevent的monkey补丁应该提供的异步好处。在
为了测试这个,我创建了一个测试服务器。在from gevent import monkey
monkey.patch_all()
from flask import Flask
from time import sleep
import requests
app = Flask(__name__)
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n - 1) + fib(n - 2)
@app.route('/')
def hello_world():
return 'Hello, World!'
@app.route('/sleep/')
def sleep_view(n):
sleep(n)
return f'Slept {n}'
@app.route('/slowreq')
def slowreq_view():
res = requests.get('http://localhost:8002/sleep/5')
return 'From another server: ' + res.text
@app.route('/fib/')
def fib_view(n):
x = fib(n)
return str(x)
if __name__ == '__main__':
import sys
port = 8001
threaded = False
if len(sys.argv) > 1:
port = int(sys.argv[1])
threaded = True
print(f'Threaded is {threaded}')
app.run(port=port, threaded=threaded)
如果我在两个进程中运行它,首先使用python3 test.py(在8001上运行,flask是非线程的,但是monkey-patched),然后是python3 test.py 8002(在8002上运行,flask是线程化的,也是monkey patched),我预计会发生以下情况:在两个终端中,我一个接一个地快速运行time curl http://localhost:8001/slowreq。/slowreq调用另一台服务器上的/sleep/5,因此作为独立请求,它应该需要5秒钟。在
8001上的服务器接收请求并用requests.get调用8002服务器。Requests是urllib3上的包装器,它是socket上的stdlib包装器,默认情况下,gevent.monkey.patch_all()修补程序(socket=True是默认值)。由于monkey补丁,我希望服务器等待响应。在
8002服务器接收/sleep/5请求,休眠5秒,然后响应。因为它是一个线程服务器,所以可以同时发生多个休眠。在
在非monkey补丁的情况下,我预计第一个/slowreq请求需要5秒,第二个请求需要10秒,这就是我看到的。在
但是,在monkey patched的情况下,我希望8001服务器不再阻塞requests.get调用,因此这两个请求都需要5秒钟的时间。这并不是所发生的,其行为与非猴子修补的情况相同。在
因此,我的问题是:猴子修补能达到什么目的,我如何利用它的好处?在