2017-01-17 21 views
0

友人がPopenの実行が終了した後にコールバックが実行されるように、コードを書きたいと思っていました。ここで要求されるものの例プログラムがあり、適切な答えを開発を支援する必要がありますPopenでコールバックを登録するにはどうすればいいですか?

#! /usr/bin/env python3 
from subprocess import Popen 


def main(): 
    handle = Popen(('cmd', '/c', 'pause')) 
    handle.register_callback(Popen, ('cmd', '/c', 'echo', 'THE END')) 


if __name__ == '__main__': 
    main() 

APIでregister_callback方法を提供する最も簡単な方法は何ですか?

答えて

0

Popenから継承し、register_callbackメソッドを提供する別のクラスを導入することです。

#! /usr/bin/env python3 
from subprocess import Popen 
from threading import Thread 


def main(): 
    handle = Process(('cmd', '/c', 'pause')) 
    handle.register_callback(Process, ('cmd', '/c', 'echo', 'THE END')) 


class Process(Popen): 

    def register_callback(self, callback, *args, **kwargs): 
     Thread(target=self.__bootstrap, args=(callback, args, kwargs)).start() 

    def __bootstrap(self, callback, args, kwargs): 
     self.wait() 
     callback(*args, **kwargs) 


if __name__ == '__main__': 
    main() 

この答えは、すべてのアプリケーションに適していないかもしれないが、与えられた状況で動作します:次のプログラムは、これが容易に可能である方法を示しています。

+1

をできるだけ早く '__bootstrapとしては、 () 'メソッドが呼び出されると、メインスレッドはプロセスが終了するまでブロックします。それだけのことがあれば、 'self.wait()'(または 'handle.wait()')を直接呼び出すのはどうですか? – martineau

+0

おそらくこれは最小の例なのでしょうか?このコードは単に 'register_callback'メソッドが実際に有用であるはるかに大きくて複雑なプログラムを単に表すものであると考えられます。 –

+0

追加の制約がある場合は、(あなたが投稿したので)質問にそれらの概要を示す必要があります。 – martineau

1

、それは他のことを行うことができますので、メインスレッドの処理をブロックしないようにするためには、あなたがそれを行うのかどうかを確認するためににポーリングプロセスを別のスレッドを作成することができます。

from subprocess import Popen 
from threading import Thread 
import time 

class Process(Popen): 
    def register_callback(self, callback, *args, **kwargs): 
     Thread(target=self._poll_completion, args=(callback, args, kwargs)).start() 

    def _poll_completion(self, callback, args, kwargs): 
     while self.poll() is None: 
      time.sleep(0.1) 
     callback(*args, **kwargs) 

def main(): 
    handle = Process(('cmd', '/c', 'echo', 'process finished')) 
    handle.register_callback(my_callback) 

def my_callback(): 
    print("It's done!") 

if __name__ == '__main__': 
    main() 
関連する問題