一位朋友想要编写一些代码,以便在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 :(得分: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()
答案 1 :(得分: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()
这个答案可能并不适用于所有应用程序,但在特定情况下有效。