![](/img/trans.png)
[英]How to run a blocking task asynchronously with ProcessPoolExecutor and asyncio?
[英]How can I launch a blocking task from asyncio asynchronously?
我是asyncio的新手,正在尝试制作一个简单的Web服务器,该服务器在收到请求后会计算下棋动作并将结果作为响应返回。 问题是,进程正在阻塞,从而使Web服务器在评估时无法侦听请求并对请求做出反应。 我觉得我已经很接近了,但是无法弄清楚接下来的几个步骤才能使这项工作正常进行。 我已经使国际象棋引擎可以在另一个脚本中的多个不同线程中运行,现在我只需要知道如何将其集成到简单的Web服务器中即可。 任何帮助,将不胜感激。 这是我的代码:
import asyncio
from aiohttp import web
import chess.engine
from concurrent.futures import ThreadPoolExecutor
import json
engine = chess.engine.SimpleEngine.popen_uci("/usr/games/stockfish")
executor = ThreadPoolExecutor(max_workers=3)
def play():
global engine
fen = "rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2"
print(fen)
board = chess.Board(fen)
result = engine.play(board,chess.engine.Limit(time=15.0))
return result
async def run_blocking_task(executor):
loop = asyncio.get_event_loop()
result = await loop.run_in_executor(executor, play)
return result
async def hello(request):
result = await run_blocking_task(executor)
return web.Response(text=str(result.move))
app = web.Application()
app.add_routes([web.get('/', hello)])
loop = asyncio.get_event_loop()
handler = app.make_handler()
f = loop.create_server(handler, '0.0.0.0', 8080)
srv = loop.run_until_complete(f)
print('serving on', srv.sockets[0].getsockname())
try:
loop.run_forever()
except KeyboardInterrupt:
pass
finally:
loop.run_until_complete(handler.finish_connections(1.0))
srv.close()
loop.run_until_complete(srv.wait_closed())
loop.run_until_complete(app.finish())
loop.close()
总体而言,您的代码看起来不错。 您遇到的问题是Python的有限线程支持。
尝试将ThreadPoolExecutor
交换为ProcessPoolExecutor
( from concurrent.futures import ProcessPoolExecutor
),这将在单独的进程中运行引擎任务,从而允许该任务实际并行运行。
为了扩展线程问题,Python解释器具有一个锁(称为GIL),该锁仅允许一次在一个线程上执行Python代码。 这大大简化了大多数开发任务。 在某些情况下释放该锁,调用内核执行IO(从文件或网络读取)将释放GIL,从而使IO成为线程化的良好用例。 ProcessPoolExecutor
使用自己的单独的解释器在单独的进程中执行您的工作程序任务,使您的代码可以并行运行,这种方法会带来一些开销,但是在现代计算机的情况下,这是非常小的。 ProcessPoolExecutor
将为您自动处理在每个流程之间移动数据的流程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.