Используем блокировки в асинхронном программирование в языке microPython используя микроконтроллер ESP8266.

В данном уроке мы рассмотрим такое понятие как блокировка.

Блокировка нам может понадобится когда несколько ресурсов дерутся за право выполнения. Но нам  необходимо, что бы каждый ресурс был обработан, и только после этого начал обрабатываться следующий ресурс.

И так, для примера, у нас есть 4 светодиода (каждый светодиод символизирует некий процесс): в начале необходимо, что бы выполнился процесс один (первый светодиод), потом второй и третий и далее заново. Причем четвертый процесс должен выполнятся постоянно, вне зависимости от выполнения предыдущих.

Для решения нашей задачи существует lock.acquire(), данная команда блокирует доступ ресурса к подпрограмме, пока она не будет полностью обработана (выполнена), точнее сказать когда программа дойдет до строчки lock.release().

Посмотрим реализацию данной задачи в микроконтроллере ESP8266, на языке microPython:

Программный код:

import uasyncio as asyncio
import uasyncio
from machine import Pin
D1=Pin(5, Pin.OUT)
D2=Pin(4, Pin.OUT)
D3=Pin(0, Pin.OUT)
D5=Pin(14, Pin.OUT)

async def task(i, lock):
while True:
     await lock.acquire()
     print("Task", i)
     if i == 1:
        D1.on()
     elif i == 2:
     D2.on()
   elif i == 3:
    D3.on()
   await asyncio.sleep(1)
  if i == 1:
    D1.off()
elif i == 2:
  D2.off()
elif i == 3:
  D3.off()
lock.release()

async def kil ():
   await asyncio.sleep(30)
   D1.off()
   D2.off()
   D3.off()
D5.off()

async def blink():
    while True:
   D5.on()
   await asyncio.sleep(0.7)
      D5.off()
      await asyncio.sleep(0.6)

loop = asyncio.get_event_loop()
lock = uasyncio.Lock()

loop.create_task(task(1, lock))
loop.create_task(task(2, lock))
loop.create_task(task(3, lock))
loop.create_task(blink())

#loop.run_until_complete(kil())
loop.run_forever()

Разберем программный код: 

Мы создали 3 подпрограммы которые используют один и тот же ресурс, если мы разрешим одновременно доступ всех 3-ех подпрограмм к данному ресурсу, мы получим хаотичное их выполнение. Что бы этого не было, мы разрешаем только одной подпрограмме использовать данный ресурс — lock.acquire(), после того как подпрограмма была выполнена, мы снимаем блок —  lock.release(), тем самым даем доступ другой подпрограмме.