简体   繁体   English

如何使用 asyncio 运行两个函数?

[英]How to run two functions with asyncio?

I'm very confused by asyncio .我对asyncio很困惑。 My applications work fine separately, but when I try to combine them into one file, they fail.我的应用程序单独工作正常,但是当我尝试将它们组合到一个文件中时,它们会失败。

  1. I want my chess engine to run: start_engine()我希望我的国际象棋引擎运行: start_engine()

  2. I also want my websockets server to run: hello()我还希望我的websockets服务器运行: hello()

I want to communicate with my chess engine using websockets over the lan, so I need them both running at the same time.我想通过局域网使用websockets与我的国际象棋引擎通信,所以我需要它们同时运行。

import asyncio
import chess
import chess.engine
import websockets


async def hello(websocket, path):
    fen = await websocket.recv()
    print(f"< {fen}")

    response = f"Got: {fen}"

    await websocket.send(response)
    print(f"> {response}")


async def start_engine(engine, board):
    fen = "2k1r3/pR2bp2/2p1p3/N3P1p1/1PP2n2/P4P2/7r/2K2BR1 b - - 0 28"
    board = chess.Board(fen)
    print(board)
    with await engine.analysis(board, multipv=1) as analysis:
        async for info in analysis:
            try:
                score = info.get("score")
                pv = info.get("pv")[0]
                depth = info.get("seldepth")
                # I want to stream this data infinitely to the websocket client
                print(score, pv, depth)
            except:
                continue

            if info.get("seldepth", 0) > 15:
                break
    await engine.quit()

async def main():    
    engine_path = "/usr/local/bin/stockfish"
    transport, engine = await chess.engine.popen_uci(engine_path)

    board = chess.Board()
    await start_engine(engine, board)


start_server = websockets.serve(hello, "localhost", 11111)
asyncio.get_event_loop().run_until_complete(start_server)
asyncio.get_event_loop().run_forever()
asyncio.run(main())

I believe the error is in the last few lines.我相信错误出现在最后几行。 In this case, the websockets server runs fine, but the chess engine never runs.在这种情况下,websockets 服务器运行良好,但国际象棋引擎从未运行。

I'm assuming this is because asyncio.get_event_loop().run_forever() is above asyncio.run(main())我假设这是因为asyncio.get_event_loop().run_forever()高于asyncio.run(main())

If I comment out the asyncio run_forever() lines from the bottom, the chess engine runs fine but the websockets server does not run.如果我从底部注释掉 asyncio run_forever()行,则国际象棋引擎运行良好,但 websockets 服务器不运行。

How can I have both services running?我怎样才能同时运行这两个服务?

(I'm literally using the tutorial code for both services: websockets , and the chess engine ) (我实际上是在使用这两种服务的教程代码: websocketschess engine

I believe the error is in the last few lines.我相信错误出现在最后几行。

Yes.是的。 In particular the function run_forever() , as its name implies, runs forever, so the next line is never executed.特别是 function run_forever() ,顾名思义,永远运行,所以下一行永远不会执行。

The fix is to avoid run_forever , move all top-level logic to main , and issue a single asyncio.run at top-level.解决方法是避免run_forever ,将所有顶级逻辑移至main ,并在顶级发出单个asyncio.run Inside async code run_until_complete can be replaced with await .内部异步代码run_until_complete可以替换为await For example (untested):例如(未经测试):

async def main():
    await websockets.serve(hello, "localhost", 11111)

    engine_path = "/usr/local/bin/stockfish"
    transport, engine = await chess.engine.popen_uci(engine_path)

    board = chess.Board()
    await start_engine(engine, board)

asyncio.run(main())

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

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