【解決?】subprocessを非同期実行しつつ、確実にkillしたい
具体的にはarecordで音声ストリームを取得しつつ、任意のイベントを受け取るかデストラクタで確実にkillしたい。
以下のような一連のコードをThreadで実行している。
self.buff = Queue.Queue(1000) reccmd = ["arecord", "-f", "S16_LE", "-r", "16000", "-t", "raw", "-q"] process = subprocess.Popen(reccmd, stdout=subprocess.PIPE) logger.debug("start buffering process") self.flag_Buffering = True while self.flag_Buffering: self.buff.put(process.stdout.read(2048)) logger.debug("killing buffering process") process.kill()
時たまkillできずに子プロセスが居残っているのか、再度実行した時にクラッシュする。
無限ループをフラグで管理している部分が怪しい。
デストラクタでのフラグ変更は確実に呼び出される保証が無いが、 with文なら上手くいく…?
withクラスの実装。
2018年1月30日追記
発話区間の音声を取得するためにbuffというQueueを作り、 発話の検知イベントの遅れを加味して発話前のコンマ数秒からbuffに残し、 発話終わりのイベントが来たタイミングで録音終了、subprocessをkillしたかった。
そもそも別スレッドで実行する必要が無かったので メインスレッドのイベントループ内でstdout.read()した。
素直に動いてくれたけどタイトルの非同期実行しつつ確実にkillは相変わらず不明。 withか。
その他備忘録メモ
process.stdout.read()を使う時にパイプバッファが詰まって デッドロックするのでcommunicate()を使おうという記事を多々見たが ストリームの取得はstdout.read()しか方法が無い様子