栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

在Python中,我怎么知道进程何时完成?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

在Python中,我怎么知道进程何时完成?

这个答案真的很简单!(花了我 几天的时间 来解决。)

与PyGTK的idle_add()结合使用,可以创建一个AutoJoiningThread。总代码是微不足道的:

class AutoJoiningThread(threading.Thread):    def run(self):        threading.Thread.run(self)        gobject.idle_add(self.join)

如果您想做的不只是加入(例如收集结果),还可以扩展上面的类以在完成时发出信号,如以下示例所示:

import threadingimport timeimport sysimport gobjectgobject.threads_init()class Child:    def __init__(self):        self.result = None    def play(self, count):        print "Child starting to play."        for i in range(count): print "Child playing." time.sleep(1)        print "Child finished playing."        self.result = 42    def get_result(self, obj):        print "The result was "+str(self.result)class AutoJoiningThread(threading.Thread, gobject.GObject):    __gsignals__ = {        'finished': (gobject.SIGNAL_RUN_LAST,          gobject.TYPE_NONE,          ())        }    def __init__(self, *args, **kwargs):        threading.Thread.__init__(self, *args, **kwargs)        gobject.GObject.__init__(self)    def run(self):        threading.Thread.run(self)        gobject.idle_add(self.join)        gobject.idle_add(self.emit, 'finished')    def join(self):        threading.Thread.join(self)        print "Called Thread.join()"if __name__ == '__main__':    print "Creating child"    child = Child()    print "Creating thread"    thread = AutoJoiningThread(target=child.play,         args=(3,))    thread.connect('finished', child.get_result)    print "Starting thread"    thread.start()    print "Running mainloop (Ctrl+C to exit)"    mainloop = gobject.MainLoop()    try:        mainloop.run()    except KeyboardInterrupt:        print "Received KeyboardInterrupt.  Quiting."        sys.exit()    print "God knows how we got here.  Quiting."    sys.exit()

上面示例的输出将取决于线程执行的顺序,但是它将类似于:

创造孩子创建线程启动线程孩子开始玩。 小孩玩。运行主循环(Ctrl + C退出)小孩玩。小孩玩。孩子玩完了。叫做Thread.join()结果是42^ C收到KeyboardInterrupt。退出

以相同的方式创建AutoJoiningProcess是不可能的(因为我们不能在两个不同的进程之间调用idle_add()),但是我们可以使用AutoJoiningThread来获得我们想要的:

class AutoJoiningProcess(multiprocessing.Process):    def start(self):        thread = AutoJoiningThread(target=self.start_process)        thread.start() # automatically joins    def start_process(self):        multiprocessing.Process.start(self)        self.join()

为了演示AutoJoiningProcess,这里是另一个示例:

import threadingimport multiprocessingimport timeimport sysimport gobjectgobject.threads_init()class Child:    def __init__(self):        self.result = multiprocessing.Manager().list()    def play(self, count):        print "Child starting to play."        for i in range(count): print "Child playing." time.sleep(1)    print "Child finished playing."        self.result.append(42)    def get_result(self, obj):        print "The result was "+str(self.result)class AutoJoiningThread(threading.Thread, gobject.GObject):    __gsignals__ = {        'finished': (gobject.SIGNAL_RUN_LAST,          gobject.TYPE_NONE,          ())    }    def __init__(self, *args, **kwargs):        threading.Thread.__init__(self, *args, **kwargs)        gobject.GObject.__init__(self)    def run(self):        threading.Thread.run(self)        gobject.idle_add(self.join)        gobject.idle_add(self.emit, 'finished')    def join(self):        threading.Thread.join(self)        print "Called Thread.join()"class AutoJoiningProcess(multiprocessing.Process, gobject.GObject):    __gsignals__ = {        'finished': (gobject.SIGNAL_RUN_LAST,          gobject.TYPE_NONE,          ())        }    def __init__(self, *args, **kwargs):        multiprocessing.Process.__init__(self, *args, **kwargs)        gobject.GObject.__init__(self)    def start(self):        thread = AutoJoiningThread(target=self.start_process)        thread.start()    def start_process(self):        multiprocessing.Process.start(self)        self.join()        gobject.idle_add(self.emit, 'finished')    def join(self):        multiprocessing.Process.join(self)        print "Called Process.join()"if __name__ == '__main__':    print "Creating child"    child = Child()    print "Creating thread"    process = AutoJoiningProcess(target=child.play,         args=(3,))    process.connect('finished',child.get_result)    print "Starting thread"    process.start()    print "Running mainloop (Ctrl+C to exit)"    mainloop = gobject.MainLoop()    try:        mainloop.run()    except KeyboardInterrupt:        print "Received KeyboardInterrupt.  Quiting."        sys.exit()    print "God knows how we got here.  Quiting."    sys.exit()

产生的输出将与上面的示例非常相似,除了这次我们同时具有流程联接和伴随的线程联接:

创造孩子创建线程启动线程运行主循环(Ctrl + C退出) 孩子开始玩。小孩玩。小孩玩。小孩玩。孩子玩完了。称为Process.join()结果是[42]叫做Thread.join()^ C收到KeyboardInterrupt。退出

不幸:

  1. 由于使用了idle_add(),因此此解决方案取决于gobject。gobject由PyGTK使用。
  2. 这不是真正的父母/子女关系。如果这些线程之一是由另一个线程启动的,那么它将由运行mainloop的线程(而不是父线程)加入。这个问题也适用于AutoJoiningProcess,除非我想象会抛出异常。

因此,要使用这种方法,最好只在mainloop / GUI中创建线程/进程。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/645392.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号