代码之家  ›  专栏  ›  技术社区  ›  Chameleon

如何在Windows和Python 3.7+中检查asyncio StreamReader中是否有要读取的内容?

  •  0
  • Chameleon  · 技术社区  · 7 年前

    它的工作原理如下:

    1. 它立即将一些行输入stdout进行响应。
    2. 它可以连续响应下一行(新移动评估)。
    3. Stockfish永远不应该停止这样做 communicate() 不会工作,因为它不是设计师。 add_reader

    它不断地发送不可预测的行数。

    问题是我什么时候打电话 await stdout.readline() 我不想阻塞程序流,但检查新行是否被读取为读取。我怎样才能不阻塞地读行呢。

    我所做的一些代码-不复杂:

    import asyncio
    
    import sys
    
    
    def stockfish_read_stdout(line):
        print(line)
    
    
    async def run_stockfish():
        STOCKFISH_PATH = r'C:\root\chess\stockfish\stockfish 9\stockfish_9_x64_bmi2.exe'
    
        stockfish = await asyncio.subprocess.create_subprocess_exec(
            STOCKFISH_PATH,
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
    
        # It is maybe not work since output is not complete.
        stockfish.stdin.write('uci'.encode())
    
        # How to check if line read to read?
        # I put True but here should be check.
        while True:
            line = await stockfish.stdout.readline()
            print(line)
    
        await stockfish.wait()
    
    
    if sys.platform == "win32":
        asyncio.set_event_loop_policy(
            asyncio.WindowsProactorEventLoopPolicy())
    
    asyncio.run(run_stockfish(), debug=True)
    

    输出为:

    Python 3.7.1 (v3.7.1:260ec2c36a, Oct 20 2018, 14:57:15) [MSC v.1915 64 bit (AMD64)] on win32
    runfile('C:/Users/Cezary Wagner/PycharmProjects/stockfish-proxy/sandbox/async_proxy/s01_async_stockfish.py', wdir='C:/Users/Cezary Wagner/PycharmProjects/stockfish-proxy/sandbox/async_proxy')
    b'Stockfish 9 64 BMI2 by T. Romstad, M. Costalba, J. Kiiski, G. Linscott\r\n'
    

    uci

    Stockfish 9 64 BMI2 by T. Romstad, M. Costalba, J. Kiiski, G. Linscott
    uci
    id name Stockfish 9 64 BMI2
    id author T. Romstad, M. Costalba, J. Kiiski, G. Linscott
    
    option name Debug Log File type string default
    option name Contempt type spin default 20 min -100 max 100
    option name Threads type spin default 1 min 1 max 512
    option name Hash type spin default 16 min 1 max 131072
    option name Clear Hash type button
    option name Ponder type check default false
    option name MultiPV type spin default 1 min 1 max 500
    option name Skill Level type spin default 20 min 0 max 20
    option name Move Overhead type spin default 30 min 0 max 5000
    option name Minimum Thinking Time type spin default 20 min 0 max 5000
    option name Slow Mover type spin default 89 min 10 max 1000
    option name nodestime type spin default 0 min 0 max 10000
    option name UCI_Chess960 type check default false
    option name SyzygyPath type string default 
    option name SyzygyProbeDepth type spin default 1 min 1 max 100
    option name Syzygy50MoveRule type check default true
    option name SyzygyProbeLimit type spin default 6 min 0 max 6
    uciok
    
    1 回复  |  直到 7 年前
        1
  •  3
  •   Chameleon    7 年前

    您需要创建一个单独的协程,它将从进程的标准输出缓冲区中读取行,因为 await 阻挡 现在的

    async def reader(process, msg_handler, exit_handler):
        while not process.stdout.at_eof():
            line = await process.stdout.readline()
            msg_handler(line.decode())
        # Finished
        exit_handler()
    

    现在可以将其作为事件循环中的任务运行。

    async def run_stockfish():
        STOCKFISH_PATH = r'C:\root\chess\stockfish\stockfish 9\stockfish_9_x64_bmi2.exe'
    
        stockfish = await asyncio.subprocess.create_subprocess_exec(
            STOCKFISH_PATH,
            stdin=asyncio.subprocess.PIPE,
            stdout=asyncio.subprocess.PIPE,
            stderr=asyncio.subprocess.PIPE)
    
        # It is maybe not work since output is not complete.
        stockfish.stdin.write('uci\n'.encode())
    
        task = asyncio.create_task(reader(stockfish,
                                          lambda msg: print(f'Output: {msg}'),
                                          lambda: print('EOF'))
    
        # asyncio.create_task won't block this coroutine
    

    希望不会太晚。