我正在尝试理解python的asyncio库,并对以下示例的行为感到有些惊讶:
import asyncio
import time
from aiohttp import web
_lock_table = {'locked': False}
async def process(text):
# wait while we're blocked
while _lock_table['locked']:
await asyncio.sleep(1)
_lock_table['locked'] = True
# hold the lock for three seconds
# simulates "processing something"
await asyncio.sleep(3)
# release the lock
_lock_table['locked'] = False
async def request_handler(request):
text = request.query.get('text')
start_time = time.time()
await process(text)
end_time = time.time()
return web.Response(
body='text: {}, request time: {}'.format(text, end_time - start_time),
content_type='text/html'
)
app = web.Application()
app.router.add_route('GET', '/', request_handler)
web.run_app(app)
如果我启动上述程序并向http://0.0.0.0:8080
打开两个请求,我发现这两个请求大约需要三秒钟才能完成。为什么是这样?第二个请求是否应该被获得锁定的第一个请求阻止?
答案 0 :(得分:0)
我无法重现你所描述的问题。 aiohttp不鼓励使用全局变量,并建议使用Application对象来支持全局变量。但他们似乎并没有提到线程涉及到这里。它似乎是一个更清晰的代码而不是必需品的一般提示 - 所以你的代码应该没问题......
我使用此示例bash脚本测试了您的代码:
#!/bin/bash
pids=()
range=$(seq 1 10)
url='http://127.0.0.1:8080/?text='
for i in $range; do
curl -o $i.txt "${url}$(date +%H%M%S)" 2>/dev/null &
pids[$i]=$!
done
wait ${pids[$@]}
for i in $range; do
echo "$i $(cat $i.txt)"
done
输出看起来像这样:
1 text: 222331, request time: 24.153167724609375
2 text: 222331, request time: 15.077209711074829
3 text: 222331, request time: 27.17816162109375
4 text: 222331, request time: 6.0150146484375
5 text: 222331, request time: 18.09979248046875
6 text: 222331, request time: 21.1268310546875
7 text: 222331, request time: 3.004944086074829
8 text: 222331, request time: 9.03411865234375
9 text: 222331, request time: 12.050049066543579
10 text: 222331, request time: 30.205841302871704
您可能希望确保实际的开始时间相似。