繁体   English   中英

如何从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交换为ProcessPoolExecutorfrom concurrent.futures import ProcessPoolExecutor ),这将在单独的进程中运行引擎任务,从而允许该任务实际并行运行。

为了扩展线程问题,Python解释器具有一个锁(称为GIL),该锁仅允许一次在一个线程上执行Python代码。 这大大简化了大多数开发任务。 在某些情况下释放该锁,调用内核执行IO(从文件或网络读取)将释放GIL,从而使IO成为线程化的良好用例。 ProcessPoolExecutor使用自己的单独的解释器在单独的进程中执行您的工作程序任务,使您的代码可以并行运行,这种方法会带来一些开销,但是在现代计算机的情况下,这是非常小的。 ProcessPoolExecutor将为您自动处理在每个流程之间移动数据的流程。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM