IO Completion Ports (IOCP) and Asynchronous I/O through STDIN, STDOUT and STDERR
tl;dr Can't be done directly. You have two options: a) mock async I/O with threads, or b) redirect STDIN, STDOUT & STDERR to other file handles that support overlapping (aka non-blocking/async) I/O,...
https://tim.mcnamara.nz/post/176613307022/iocp-and-stdio
こういうやつ
subprocess モジュール
subprocess は、
の置き換え。
subprocess.run
中でPopenして結果を集めて CompletedProcess
として返す。
実行して結果の文字列を得て終わりというタイプの用途向け。
旧 os.system
の代替になると思う。
subprocess.Popen
標準入力、標準出力を制御するのはこっち。
Readループが一個しかない時はこれでいいんでないかな。
今回のテーマ
- @のところを常時読み込みにしたい(2つのReadループ)
- @stdin をReadするとブロックして固まるのでつらい
つらいのだ。
asyncio
2つのReaderを非同期で制御しようということで 。
asyncio の基本
loop を露出させる。
loop は暗黙。 基本的にこちらでよいと思う。 必要に応じて取得する。
asyncio.create_task で新しいスタックを開始する
新しいスタックなのでエラーハンドリングが無いことに注意。
StreamReaderProtocol と StreamWriterProtocol
コールバックと Stream を結び付ける。
Windowsの標準入出力はIOCPできない
IOCPできるハンドルは決まっていて、
-
通常のファイル
-
Socket
-
NamedPipe
python3.7 で asyncio.create_subprocess
ができた
child process 側はこれで助かった。
なんか、たまに socket.exception
が出るので、
tcpのlocalhost接続にリダイレクトするとか謎の技使っているのかもしれぬ。
おかげで、子プロセスの標準入出力から StreamReader
と StreamWriter
を楽に取得できる。
重い NativeCoroutine は、ThreadPoolExecutorに逃がす
標準入力側
GILを回避して、別スレッドで待てるのではないか。
どんな処理が、NativeCoroutine なのか。