tornado异步和同步交叉使用
1 同步代码异步执行
from concurrent.futures.thread import ThreadPoolExecutor
class AsyncClient(object):
__instance = None
"""
这里做成了单例以便于使用相同线程池来处理所有这种情况
"""
def __new__(cls, *args, **kwargs):
if cls.__instance is None:
cls.__instance = super(
AsyncClient, cls).__new__(cls, *args, **kwargs)
return cls.__instance
def __init__(self):
self.executor = ThreadPoolExecutor()
self.io_loop = ioloop.IOLoop.current()
@concurrent.run_on_executor
def methods(self, syncfunc, args):
return syncfunc(args)
class AsyncRequestHandle(tornado.web.RequestHandler):
async def get(self):
client = AsyncClient()
res = await client.methods(requests.get,"https://www.baidu.com")
print(res.status_code)
self.write('ok')
await self.finish()
2 同步代码中引入异步代码时
alt_ioloop_fut = concurrent.futures.Future()
def run_alt_loop():
asyncio.set_event_loop(asyncio.SelectorEventLoop())
ioloop = IOLoop()
alt_ioloop_fut.set_result(ioloop)
ioloop.start()
alt_thread = threading.Thread(target=run_alt_loop)
alt_thread.daemon = True
alt_thread.start()
alt_ioloop = alt_ioloop_fut.result()
def run_coro_on_other_thread(f, *args, **kw):
fut = concurrent.futures.Future()
async def wrapper():
try:
res = await f(*args, **kw)
fut.set_result(res)
except Exception as e:
fut.set_exception(e)
alt_ioloop.add_callback(wrapper)
return fut.result()
async def func():
async_client = httpclient.AsyncHTTPClient()
res = await async_client.fetch('https://www.baidu.com')
return res
class Handler(tornado.web.RequestHandler):
def get(self):
res = run_coro_on_other_thread(func)
print(res.body)
self.write('ok')