andrey_u
@andrey_u

Micropython uasyncio почему одна функция тормозит другую?

Ковыряюсь с ESP32 и Micropython.

Почему во время запроса urequests.get в f2() тормозит и функция f1(), подскажите в чем проблема и как можно исправить?

Мне нужно чтобы код в f1() строго выполнялся каждые 50 ms и переодически отсылать данные через urequests в f2().

import time
import uasyncio
import urequests


async def f1():
    t1 = time.ticks_ms()
    while True:
        print(time.ticks_ms() - t1)
        t1 = time.ticks_ms()
        await uasyncio.sleep_ms(50)


async def f2():
    while True:
        r = urequests.get('https://timeapi.io/api/Time/current/zone?timeZone=Europe/Moscow').text
        #print(r)
        await uasyncio.sleep_ms(500)

    
def do_connect():
    import network
    sta_if = network.WLAN(network.STA_IF)
    if not sta_if.isconnected():
        print('connecting to network...')
        sta_if.active(True)
        sta_if.connect('wi-fi name', 'pass')
        while not sta_if.isconnected():
            pass
    print('network config:', sta_if.ifconfig())
    
    
loop = uasyncio.get_event_loop()
    
loop.create_task(f1())    
loop.create_task(f2())    

do_connect()
loop.run_forever()


Вот что выдает код ->

50
50
50
50
50
50
50
50
50
1394
56
50
50
50
50
50
50
50
50
1386
53
50
50
50
50
50
50
50
50
1391
58
50
50
50
50
50
50
50
50
1383
57
50
50
50
50
50
50
50
50
1388
51
50
50
50
50
50
50
50
50
1395
55
50
50
50
50
50
50
50
50
1383
57
50
50
50
50
50
50
50
50
1390
59
50
50
50
50
50
50
50
50
  • Вопрос задан
  • 115 просмотров
Пригласить эксперта
Ответы на вопрос 2
@deliro
Во-первых, urequests.get у тебя блокирующая (с micropython не знаком, но await там у тебя нет и не похоже, что возвращается future)
Во-вторых, ровно каждые 50мс выполняться оно не будет. sleep ставит в хип таску с приоритетом «текущее время» + время сна. Этот хип разбирается на каждом шаге event loop, но никто не гарантирует, что шаг отработает, допустим, не за 500мс, тогда твоя таска исполнится только через полсекунды. Ну и блокирующий вызов urequests это лишний раз подтверждает

В общем, sleep - это «усни минимум на x времени», а блокирующий вызов http надо заменить на асинхронный
Ответ написан
Комментировать
mayton2019
@mayton2019
Bigdata Engineer
Вывод на экран через print(..) может нарушить временнУю картину мира.
Вредная штука этот экран. Блокирующий. Тоже добавит свои погрешности.

Особенно когда 100 потоков что-то пишут в экран может оказаться что все они только
и ждут экрана.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы