概要
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
まとめと今後の課題
比較的簡単に、非同期処理が実装できた。