You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Tornado并发处理机制及多请求场景下的CPU状态疑问

问题与解答:Tornado多进程下慢IO请求的处理情况

我们有一个基于Tornado的Web应用,通过fork 4个子进程运行,核心代码如下:

主进程启动代码:

async def post_fork_main():
    app = tornado.web.Application([(r'/', MyHandler)])
    server = tornado.httpserver.HTTPServer(app)
    server.add_sockets(sockets)
    await asyncio.Event().wait()
    

if __name__ == '__main__':
    sockets = tornado.netutil.bind_sockets(8080)
    tornado.process.fork_processes(4)
    print("Service is started successfully ...")
    asyncio.run(post_fork_main())

请求处理Handler代码:

class MyHandler(tornado.web.RequestHandler):
    async def get(self):
        # some other processing code.
        await call_api()   # reply very slowly.
        # some other processing code.
        self.write('OK')

疑问

当4个子进程都处于等待call_api()(响应极慢)返回的状态时,如果请求数超过4个,会发生什么?此时CPU是否近乎空闲?


回答

1. 请求超过4个时的处理逻辑

  • Tornado的每个子进程基于异步IO模型工作,单个子进程可以同时处理多个请求:当某个请求执行到await call_api()时,对应的协程会被挂起,子进程的事件循环会立刻去处理队列中其他等待的请求,不会被这个慢IO操作阻塞。
  • 新来的请求会先被操作系统的TCP监听队列(backlog)暂存,只要队列没满,请求就不会丢失;当某个子进程的事件循环有空(比如某个call_api()完成,协程执行完毕),就会从队列中取出新请求进行处理。
  • 如果请求量持续超过TCP队列的承载上限,后续的请求会被操作系统直接拒绝,客户端会收到类似Connection Refused的错误。

2. CPU使用状态

  • 此时CPU会近乎空闲。因为所有子进程的事件循环在等待IO完成时,挂起的协程不会占用CPU时间片——await关键字会让事件循环释放CPU资源,直到call_api()的IO操作完成、协程被唤醒后,才会短暂占用CPU执行后续代码(比如self.write('OK'))。大部分时间里CPU处于等待IO响应的空闲状态。

内容的提问来源于stack exchange,提问作者taichi_tiger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 12:43:16