测试版本:Python3.8 Torando6.4
1、非正常异步代码-实际同步:
async def sl():
time.sleep(0.2) # 同步等待 2 秒
class AsyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
await sl()
self.write("Async sleep completed!")
结论
顺序输出,50次用时10s,原因是异步函数中存在同步函数,await时按同步处理
2、非正常异步代码-跳过等待:
async def sl():
time.sleep(0.2) # 同步等待 2 秒
class AsyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
sl()
self.write("Async sleep completed!")
结论
瞬间输出(0.06s<<0.2s),存在警告,sl()未await,即跳过等待
3、正常异步代码:
class AsyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
await asyncio.sleep(0.2) # 异步等待
self.write("Async sleep completed!")
结论
0.2s输出,50次用时0.2s,标准异步实现
4、正常同步代码:
class SyncSleepHandler(tornado.web.RequestHandler):
def post(self):
time.sleep(0.2) # 同步等待 2 秒
self.write("Sync sleep completed!")
结论
50次用时10s,同步实现,等时间距离逐个输出
4.5、同步代码中插入await:
class SyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
time.sleep(0.2) # 同步等待 2 秒
await asyncio.sleep(0.2) # 异步等待
self.write("Sync sleep completed!")
结论
50次用时10.4s,同步实现,集中阻塞返回(偶尔有单个先返回)。表现为await多个请求,最糟糕。正确方法见7.5
5、正常异步代码-借助线程池:
from concurrent.futures import ThreadPoolExecutor
import tornado.web
executor = ThreadPoolExecutor()
def blocking_sleep():
time.sleep(0.2) # 同步等待 0.2 秒
async def sl():
await tornado.ioloop.IOLoop.current().run_in_executor(executor, blocking_sleep)
class AsyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
await sl()
self.write("Async sleep completed!")
结论
50次用时0.6s(受限于线程池大小),借助线程池实现异步调用,适合cpu密集任务
6、非正常异步代码-借助协程池-跳过等待
import asyncio
import tornado.web
async def blocking_sleep():
time.sleep(0.2) # 同步等待 0.2 秒
class AsyncSleepHandler(tornado.web.RequestHandler):
async def post(self):
await asyncio.get_running_loop().run_in_executor(None, blocking_sleep)
self.write("Async sleep completed!")
结论
50次用时0.06s(<<0.2s),非正确使用协程池,函数跳过等待
7、正常异步代码-借助协程池
class AsyncSleepHandler(tornado.web.RequestHandler):
def initialize(self):
self.executor = tornado.concurrent.futures.ThreadPoolExecutor()
@tornado.concurrent.run_on_executor # 同步的阻塞函数转换为异步操作,并在协程池中执行。
def sl(self):
time.sleep(0.2) # 同步等待 0.2 秒
async def post(self):
await self.sl()
self.write("Async sleep completed!")
def on_finish(self):
self.executor.shutdown(wait=False)
结论
50次用时0.26s(~0.2s),正确使用协程池,适合IO密集任务
7.5、异步代码插入同步函数-借助协程池
import threading
# 创建一个锁对象
lock = threading.Lock()
class SyncSleepHandler(tornado.web.RequestHandler):
def initialize(self):
self.executor = tornado.concurrent.futures.ThreadPoolExecutor()
def on_finish(self):
self.executor.shutdown(wait=False)
@tornado.concurrent.run_on_executor()
def blocking_sleep(self):
with lock: # 防止资源竞争
time.sleep(0.2) # 同步等待 0.2 秒
async def post(self):
await self.blocking_sleep() # 同步等待 2 秒
await asyncio.sleep(0.2) # 异步等待
self.write("Sync sleep completed!")
结论
50次用时10.6s