Heisenbug: запуск asyncio в режиме отладки приводит к лучшему времени отклика - PullRequest
0 голосов
/ 28 октября 2019

Я создал приложение управления полетом, в котором команды отправляются через последовательный порт через RF на RPi, который получает команды и выполняет их для выполнения таких операций, как серво управления.

Я выполнял этот код наПи находился в режиме отладки в течение нескольких месяцев, пока я его разрабатывал, чтобы я мог видеть сообщения о медленно работающих сопрограммах. Теперь, когда приложение почти завершено, я попытался отключить режим отладки и обнаружил, что оно стало намного менее отзывчивым - команды джойстика, отправленные, например, на RPi, теперь имеют заметную задержку с момента перемещения джойстика до времени, когдасервопривод, подключенный к RPi, фактически перемещен - команды, похоже, на некоторое время застряли в очереди приема, если многие были отправлены, а затем все выполнялись несколько секунд спустя (вместо выполнения команд по мере их поступления).

Очевидно, что я не могу поместить весь код здесь, но ниже приведены исключения из кода на стороне RPi (где наблюдается аномалия), показывающие основные сопрограммы:

import asyncio
import SerialTransport

kite = kite_setup(... serial ports, etc... )
...
async def multiplexer(loop):
    ...
    # the main coroutines:
    serial_w   = write_status()
    serial_r   = read_cmds(loop)  
    execer     = exec_cmds()
    control    = kite_control_loop()

    results = await asyncio.gather(serial_w, serial_r, execer, control, return_exceptions=True)
    handle_results(results)

async def kite_control_loop():
    logging.info("... kite_control_loop started ...")
    while True:
        ControlKite(kite)
        await asyncio.sleep(0)

async def read_cmds(loop=None):
    logging.debug(".... Starting read_cmds() ....")
    while True:
        try:
            #read from serial port into rx_fifo
            await kite.serial.read_serial_port(kite)
        except asyncio.TimeoutError:
            logging.warn("!!! TimeoutError caught on read_serial_port !!!")
        except: 
            logging.warn("!!! Some other error in read_serial_port !!!")
        logging.debug("XXX> read_cmds(): after read_serial_port()")
        await asyncio.sleep(0)

async def exec_cmds():
    while True:
        command_data = await SerialTransport.rx_fifo.get()
        command = command_factory(command_data.cmd, command_data.data)
        command.exec(kite)
        logging.debug("XXX> exec_cmds: exec'ed")
        await asyncio.sleep(0)

async def write_status():
    logging.info("Starting write_status()")
    while True:
        await kite.serial.send_serial_update(kite)        # send status update
        await asyncio.sleep(0.5)

...
loop = asyncio.get_event_loop()
loop.set_debug(True) #if commented, performance is degraded
loop.run_until_complete(multiplexer(loop))
loop.close()

Как отмечено в комментариивыше, если прокомментирована строка с loop.set_debug (True) (что означает, что отладка отключена), производительность заметно ухудшается, что кажется очень противоречивым. Есть идеи, почему это так? Обратите внимание, что, согласно отладчику asyncio, единственная сопрограмма, для которой здесь требуется более 0,1 секунды, это kite_conrol_loop, который обычно занимает чуть больше времени (обычно около 0,12 секунды, но часто менее 0,1 секунды) - это кажется довольноразумно и, как я уже отмечал ранее, в режиме отладки производительность приемлема.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...