MicroPython的午睡(111) ESP32版、乱数をdequeにつめて非同期タスク

Joseph Halfmoon

今回使用してみるMicroPythonモジュールは、collections, randomそしてuasyncioです。uasyncioで非同期動作のタスク間を、collections.dequeで作ったFIFOで橋渡し、randomモジュールで生成した乱数を受けわたそうというのです。ありがち。短いコードで動作確認。

※「MicroPython的午睡」投稿順 Indexはこちら

collections, randomそしてuasyncio

いつもお世話になっておりますMicroPythonの日本語マニュアルページが以下に。

collections — コレクションとコンテナのデータ型

random — 乱数の生成

uasyncio — 非同期 I/O スケジューラ

上記のものどもは皆「標準の」PythonにもあるモジュールのMicroPython向けのサブセットではないかと思います。この手のモジュールは、ほぼほぼフルPythonにクリソツの関数が用意されていることもあれば、かなり控えめなサブセットであったりと、まあ使ってみないとよくわかりませぬ。

実験用のソース

実験用のMicroPythonスクリプトが以下に。2つある関数 prod()とmain()は双方ともasync扱いです。こっちゃが止まればあちらが動きという塩梅で、それぞれ勝手なタイミングで動作する「タスク」です。

collections.dequeは先入れ、先出し操作が可能なFIFOみたいなものです。2つの非同期タスクの一方に開いた入口から、他方の出口につながるトンネルのようなもんですな。

本来であれば何か有用な通信や計測などのデータを流すところですが、今回はサンプルとてRandomモジュール発生による疑似乱数を荷物としてます。

入口側(生産者)のタイミングは意図的にバラつかせており、出口側(消費者)のタイミングは一定周期です。

import collections
import random
import uasyncio

queue = collections.deque((), 7, 1)

async def prod(lLim, uLim):
    while True:
        itvl = random.randint(lLim, uLim)
        queue.append(itvl)
        await uasyncio.sleep_ms(itvl)
        
async def main():
    uasyncio.create_task(prod(1000, 1100))
    while True:
        try:
            fromTask = queue.popleft()
        except IndexError:
            fromTask = 0
        print("fromTask: {}".format(fromTask))
        await uasyncio.sleep_ms(1050)
            
if __name__ == "__main__":
    print("ESP32, AsyncIO and deque.")
    uasyncio.run(main())
実行結果

上記のスクリプトを実行したところが以下に。AsyncIODequeResult

とくに問題なく受け渡せているのではないかと。知らんけど。とくに問題なく受け渡せているのではないかと。知らんけど。

MicroPython的午睡(110) ESP32版、btree + json が一番お楽? へ戻る

MicroPython的午睡(112) ESP32版、heapqで乱雑なタプルを小さい順にとりだす へ進む