工作と競馬2

電子工作、プログラミング、木工といった工作の記録記事、競馬に関する考察記事を掲載するブログ

evdevとthreadingでスイッチ操作イベントを非同期で読み取り

概要

evdevとthreadingでスイッチ操作イベントをメインスレッドとは非同期で読み取って処理する簡単な方法を調べたときのメモ。


背景と目的

evdevを使って、スイッチ操作イベントをメインスレッドとは非同期で読み取る必要が出たため方法を調べたところ、asyncioを使う方法があった。しかし、Python3系のasyncioはバージョンによって仕様差があり、今回はPython3.5を使う前提で組まなければいけない制約があるため、無難な方法としてthreadingと組み合わせた。


詳細

1.コード

ポイントは、子スレッドにdaemon=Trueを指定することと、joinで待機しないこと。これで、親スレッドが終わるといっしょに終わってくれる。

import time
import evdev
import threading

# デバイス
device = evdev.InputDevice('/dev/input/event0')

def switch_read():
    """
   スイッチイベントごとに処理
    """
    for event in device.async_read_loop():
        if event.type == evdev.ecodes.EV_KEY:
            print(evdev.categorize(event))

# スレッド作成
# switch_readを非同期で実行
th = threading.Thread(target=switch_read, daemon=True)
th.start()

# メインループ
try:
    while True:
        time.sleep(1)
        print(time.time())
except KeyboardInterrupt:
    pass

device.close()

# daemon=Trueのときはjoinしない
# th.join()


2.結果

1秒ごとの時刻表示とスイッチイベント結果が非同期で出力されている。キーボード割り込み後、ちゃんと止まった。

1588903010.0831087
key event at 1588903010.451239, 256 (['BTN_0', 'BTN_MISC']), down
key event at 1588903010.631191, 256 (['BTN_0', 'BTN_MISC']), up
1588903011.0846021
1588903012.0859232
1588903013.0873146
1588903014.0887034
key event at 1588903014.341184, 256 (['BTN_0', 'BTN_MISC']), down
key event at 1588903014.531174, 256 (['BTN_0', 'BTN_MISC']), up
1588903015.0901175
1588903016.0913897
1588903017.0927455


まとめと今後の課題

比較的簡単に、非同期処理が実装できた。