【问题标题】:Where is it stuck with 300 seconds on python aiohttp在 python aiohttp 上卡住了 300 秒
【发布时间】:2019-02-28 20:14:05
【问题描述】:

我有两个在本地运行的简单服务。 (代码如下)。为什么当我同时发送 100 个请求时,响应会在很长的 300 秒内返回。它在幕后做什么?

服务 #1,通过调用 http://localhost:8080

import os
os.environ['PYTHONASYNCIODEBUG'] = '1'
import json

from aiohttp import web
import aiohttp
import asyncio
import importlib
import time

#tasks = []
n = 0
m = 0

def mcowA(m):
   print (m, " : A") 
   return

async def fetch(session, url):
    try:
        async with session.get(url) as response:
        #async with getattr(session,"get")(url,proxy=proxy) as response:
            return await response.text()
    except Exception:
        import traceback
        traceback.format_exc()

def mcowB(n):
   print (n, " : B") 
   return

async def runMcows(request):
    start = time.time()
    global n,m
    mcowA(m)
    m=m+1
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://localhost:8081')
        #html = await fetch(session, 'http://www.cpan.org/SITES.htm
    print(n,html)
    mcowB(n)
    end = time.time()
    print ( end - start)
    n=n+1

    return web.Response(text=html)

async def init():
    app = web.Application()
    app.add_routes([web.get('/', runMcows)])
    return await loop.create_server(
        app.make_handler(), '127.0.0.1', 8080)

loop = asyncio.get_event_loop()
loop.run_until_complete(init())
loop.run_forever()

服务 2:

from aiohttp import web
import asyncio
import time

async def hello(request):
    time.sleep(5)
    #await asyncio.sleep(5)
    return web.Response(text='dummy done5')

app = web.Application()
app.add_routes([web.get('/', hello)])

web.run_app(app,host='127.0.0.1', port=8081)

我知道 time.sleep(5) 正在阻塞,但为什么它阻塞了 300 秒?哪个部分花费了 300 秒? 如果改成 await asyncio.sleep(5) 就可以了。

一些输出: https://github.com/aio-libs/aiohttp/issues/3630

【问题讨论】:

    标签: python-3.x python-asyncio aiohttp


    【解决方案1】:

    这是阻塞的。

    time.sleep(5)
    

    Asyncio 不是线程。一个事件循环正在运行,它调用你的 hello 函数,该函数在返回之前阻塞 5 秒。然后事件循环重新获得控制权并调用下一个事件,该事件将再次成为您的 hello 函数,该事件将再阻塞 5 秒,然后将控制权返回给循环。

    这会异步等待 5 秒。

    await asyncio.sleep(5)
    

    所以你的 hello 函数会立即返回,并简单地告诉循环在 5 秒内返回给我。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2021-06-29
    • 2021-05-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多