Air780EG における sys ライブラリを活用した LuaTask 非同期処理の実装

LuaTask フレームワークの概要

LuaTask は、Lua 言語のコルーチン機能を利用して擬似的なマルチタスク環境を実現するフレームワークです。従来のタイマーベースの遅延処理とは異なり、複数のタスクを並列的に記述することが可能になります。この框架を利用するには、まず sys ライブラリをロードし、プログラムの末尾で sys.run() を呼び出してスケジューラを起動する必要があります。これにより、登録されたタスクが内部ループ内で管理され実行されます。

並列タスクの生成と実行

sys.taskInit 関数を使用することで、独立した実行コンテキストを持つタスクを生成できます。各タスク内での sys.wait による遅延は、他のタスクの実行を阻害しない非ブロッキング動作となります。

local sys = require("sys")

-- 監視タスク:2 秒間隔で状態を出力
sys.taskInit(function()
    while true do
        log.info("monitor_task", "status_check")
        sys.wait(2000)
    end
end)

-- 制御タスク:0.5 秒間隔で処理を実行
sys.taskInit(function()
    while true do
        log.info("control_task", "processing")
        sys.wait(500)
    end
end)

-- フレームワークの起動
sys.run()

タスク間の同期と信号待機

タスク間の連携には、イベント発行と待機機制が用意されています。sys.publish で信号を送信し、sys.waitUntil で受信側が待機します。受信側は信号が来るまで処理を一時停止しますが、システム全体は停止しません。

local sys = require("sys")

-- 信号発行タスク
sys.taskInit(function()
    while true do
        log.info("publisher", "working")
        sys.wait(1000)
        sys.publish("EVENT_COMPLETE") -- 信号を発行
    end
end)

-- 信号待機タスク(ブロック)
sys.taskInit(function()
    while true do
        sys.waitUntil("EVENT_COMPLETE") -- 信号を受け取るまで待機
        log.info("subscriber_a", "event_received")
    end
end)

-- 信号待機タスク(タイムアウトあり)
sys.taskInit(function()
    while true do
        -- 500ms 待っても信号がなければ false を返して続行
        local result = sys.waitUntil("EVENT_COMPLETE", 500)
        log.info("subscriber_b", "wait_result", result)
    end
end)

-- コールバック形式の订阅
sys.subscribe("EVENT_COMPLETE", function()
    log.info("callback_handler", "triggered")
end)

sys.run()

上記の例では、発行タスクが 1 秒ごとに信号を出します。待機タスク A は信号が届くまで完全に停止し、タスク B は 500ms でタイムアウトするため、信号を待たずに処理を続行する場合があります。また、sys.subscribe を使用すれば、特定のイベント発生時に登録された関数を自動的に呼び出すことも可能です。

イベント経由のデータ受け渡し

信号発行時にデータを付随させることで、タスク間での情報共有が行えます。sys.publish の第二引数にデータを指定し、sys.waitUntil の戻り値で受け取ります。

local sys = require("sys")

-- データ付き信号発行
sys.taskInit(function()
    while true do
        sys.wait(1000)
        local payload = "sensor_data_123"
        sys.publish("DATA_READY", payload)
    end
end)

-- データ受信
sys.taskInit(function()
    while true do
        local success, data = sys.waitUntil("DATA_READY")
        if success then
            log.info("receiver", "data_loaded", data)
        end
    end
end)

-- コールバックでデータ取得
sys.subscribe("DATA_READY", function(val)
    log.info("cb_receiver", "value", val)
end)

sys.run()

従来のタイマー機能の利用

タスク生成以外にも、標準的なタイマー機能を提供しています。一度きりの実行や、一定間隔でのループ実行、およびタイマーの停止操作が可能です。

local sys = require("sys")

-- 1 秒後に一度だけ実行
sys.timerStart(log.info, 1000, "single_shot_timer")

-- 関数を直接定義して実行
sys.timerStart(function()
    log.info("delayed_action", "executed")
end, 1000)

-- 1 秒間隔で無限ループ実行(ID を取得)
local timer_id = sys.timerLoopStart(log.info, 1000, "loop_timer")

-- 10 秒後にループタイマーを停止
sys.timerStart(function()
    sys.timerStop(timer_id)
    log.info("cleanup", "loop_stopped")
end, 10000)

sys.run()

タグ: Air780EG lua LuaTask sys library LuatOS

6月11日 16:40 投稿