通信中の中断を受け取れない
Enchan1207 opened this issue · comments
input()
の KeyboardInterrupt
は取れるけど、通信中(コンソールで遊んでる間)に割り込ませると except
で捕捉できない
ここの try
~ except
句に KeyboardInterrupt
とか EOFError
とか挟めば補足できると思ってたけど、
普通に if __name__ == "__main__":〜
のところで例外発生してる
^D
を入力すると例外にはならなくて、少し上のコマンド文字列をコンソールから受け取るところで EOFError
を普通に捕捉して例外処理してシェルの終了処理に入る…
んー、よくわかんないけど
マルチスレッドで input()
するのが普通に間違っている気がする…
コマンド入力のところで ^C
した時にKIを受け取れるのが本来イレギュラーなんじゃないのか?これ
main自体が async def
だからこっちもここで KeyboardInterrupt
受け取れないんじゃないの (∴コマンド実行待ち中の割り込みが受け取れないとおかしい) と思ってたけど、
async def
でもメインスレッドで実行される場合がある (run_until_complete
をメインスレッドで実行した場合など)run_in_executor
は厳密にはasync def
とは異なり、内部的には別スレッドで実行される
から、
- コマンド入力中の
input
はメインスレッドで実行されているため、KeyboardInterrupt
をEOFError
を捕捉する文脈と同じ箇所で捕捉できる - コマンド実行後の処理待機(
run_in_executor
)はメインスレッドで実行されないため、KeyboardInterrupt
はそこではなくrun_until_complete
の実行元(=ソースのルート)で捕捉される
って…こと?
とりあえず main()
を async def
にするのをやめて、USBのIO遅延が生じそうなところだけ async
で処理させるようにしよう
そもそもaio自体が今回の用途に適していなかった可能性が出てきた
concurrent
のExecutor
使えばそれでいーじゃねーか!
これで少なくともコマンドの結果をやり取りする箇所でメインスレッド側での待機が発生することは無くなったな!
でも多分 future
はawaitで待てるはずだし、そうでなくてもコールバックの中で十分色々処理できる(コールバックはメインスレッドではない)から 結構色々楽な気がするぞ
コールバックを逃してインデントを減らした
荒削りですがやりたいことはできたのかなと!
closed!