<bdo id='9NbIs'></bdo><ul id='9NbIs'></ul>
  • <i id='9NbIs'><tr id='9NbIs'><dt id='9NbIs'><q id='9NbIs'><span id='9NbIs'><b id='9NbIs'><form id='9NbIs'><ins id='9NbIs'></ins><ul id='9NbIs'></ul><sub id='9NbIs'></sub></form><legend id='9NbIs'></legend><bdo id='9NbIs'><pre id='9NbIs'><center id='9NbIs'></center></pre></bdo></b><th id='9NbIs'></th></span></q></dt></tr></i><div id='9NbIs'><tfoot id='9NbIs'></tfoot><dl id='9NbIs'><fieldset id='9NbIs'></fieldset></dl></div>

      <small id='9NbIs'></small><noframes id='9NbIs'>

    1. <legend id='9NbIs'><style id='9NbIs'><dir id='9NbIs'><q id='9NbIs'></q></dir></style></legend>

      1. <tfoot id='9NbIs'></tfoot>

        在 Python 中,我如何知道一个进程何时完成?

        时间:2023-05-26
          <bdo id='Tf4GH'></bdo><ul id='Tf4GH'></ul>

              <tbody id='Tf4GH'></tbody>

            <tfoot id='Tf4GH'></tfoot>

                <i id='Tf4GH'><tr id='Tf4GH'><dt id='Tf4GH'><q id='Tf4GH'><span id='Tf4GH'><b id='Tf4GH'><form id='Tf4GH'><ins id='Tf4GH'></ins><ul id='Tf4GH'></ul><sub id='Tf4GH'></sub></form><legend id='Tf4GH'></legend><bdo id='Tf4GH'><pre id='Tf4GH'><center id='Tf4GH'></center></pre></bdo></b><th id='Tf4GH'></th></span></q></dt></tr></i><div id='Tf4GH'><tfoot id='Tf4GH'></tfoot><dl id='Tf4GH'><fieldset id='Tf4GH'></fieldset></dl></div>
                • <small id='Tf4GH'></small><noframes id='Tf4GH'>

                  <legend id='Tf4GH'><style id='Tf4GH'><dir id='Tf4GH'><q id='Tf4GH'></q></dir></style></legend>
                  本文介绍了在 Python 中,我如何知道一个进程何时完成?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  限时送ChatGPT账号..

                  我从 Python GUI (PyGTK) 中启动一个进程(使用多处理).该过程需要很长时间(约 20 分钟)才能完成.该过程完成后,我想对其进行清理(提取结果并加入该过程).我如何知道该过程何时完成?

                  From within a Python GUI (PyGTK) I start a process (using multiprocessing). The process takes a long time (~20 minutes) to finish. When the process is finished I would like to clean it up (extract the results and join the process). How do I know when the process has finished?

                  我的同事建议在父进程中使用一个繁忙的循环来检查子进程是否已完成.肯定有更好的方法.

                  My colleague suggested a busy loop within the parent process that checks if the child process has finished. Surely there is a better way.

                  在 Unix 中,当一个进程被分叉时,子进程完成后从父进程中调用信号处理程序.但我在 Python 中看不到类似的东西.我错过了什么吗?

                  In Unix, when a process is forked, a signal handler is called from within the parent process when the child process has finished. But I cannot see anything like that in Python. Am I missing something?

                  如何从父进程中观察到子进程的结束?(当然,我不想调用 Process.join(),因为它会冻结 GUI 界面.)

                  How is it that the end of a child process can be observed from within the parent process? (Of course, I do not want to call Process.join() as it would freeze up the GUI interface.)

                  这个问题不限于多处理:我对多线程也有完全相同的问题.

                  This question is not limited to multi-processing: I have exactly the same problem with multi-threading.

                  推荐答案

                  这个答案真的很简单!(我只花了 几天 来解决这个问题.)

                  This answer is really simple! (It just took me days to work it out.)

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

                  Combined with PyGTK's idle_add(), you can create an AutoJoiningThread. The total code is borderline trivial:

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

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

                  If you want to do more than just join (such as collecting results) then you can extend the above class to emit signals on completion, as is done in the following example:

                  import threading
                  import time
                  import sys
                  import gobject
                  gobject.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()
                  

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

                  The output of the above example will depend on the order the threads are executed, but it will be similar to:

                  Creating child
                  Creating thread
                  Starting thread
                  Child starting to play.
                   Child playing.
                  Running mainloop (Ctrl+C to exit)
                  Child playing.
                  Child playing.
                  Child finished playing.
                  Called Thread.join()
                  The result was 42
                  ^CReceived KeyboardInterrupt.  Quiting.

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

                  It's not possible to create an AutoJoiningProcess in the same way (because we cannot call idle_add() across two different processes), however we can use an AutoJoiningThread to get what we want:

                  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 这里是另一个例子:

                  To demonstrate AutoJoiningProcess here is another example:

                  import threading
                  import multiprocessing
                  import time
                  import sys
                  import gobject
                  gobject.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()
                  

                  生成的输出将与上面的示例非常相似,只是这次我们同时加入了进程和伴随线程:

                  The resulting output will be very similar to the example above, except this time we have both the process joining and it's attendant thread joining too:

                  Creating child
                  Creating thread
                  Starting thread
                  Running mainloop (Ctrl+C to exit)
                   Child starting to play.
                  Child playing.
                  Child playing.
                  Child playing.
                  Child finished playing.
                  Called Process.join()
                  The result was [42]
                  Called Thread.join()
                  ^CReceived KeyboardInterrupt.  Quiting.

                  不幸的是:

                  1. 由于使用了 idle_add(),此解决方案依赖于 gobject.PyGTK 使用 gobject.
                  2. 这不是真正的父子关系.如果其中一个线程是由另一个线程启动的,那么它仍然会被运行主循环的线程加入,而不是父线程.这个问题也适用于 AutoJoiningProcess,除了我想会抛出异常.

                  因此要使用这种方法,最好只从主循环/GUI 中创建线程/进程.

                  Thus to use this approach, it would be best to only create threads/process from within the mainloop/GUI.

                  这篇关于在 Python 中,我如何知道一个进程何时完成?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:使用 Python 多处理管理器 (BaseManager/SyncManager) 与远 下一篇:Python多处理附加列表

                  相关文章

                  最新文章

                • <tfoot id='yVzxW'></tfoot>
                  <i id='yVzxW'><tr id='yVzxW'><dt id='yVzxW'><q id='yVzxW'><span id='yVzxW'><b id='yVzxW'><form id='yVzxW'><ins id='yVzxW'></ins><ul id='yVzxW'></ul><sub id='yVzxW'></sub></form><legend id='yVzxW'></legend><bdo id='yVzxW'><pre id='yVzxW'><center id='yVzxW'></center></pre></bdo></b><th id='yVzxW'></th></span></q></dt></tr></i><div id='yVzxW'><tfoot id='yVzxW'></tfoot><dl id='yVzxW'><fieldset id='yVzxW'></fieldset></dl></div>

                    <bdo id='yVzxW'></bdo><ul id='yVzxW'></ul>
                • <legend id='yVzxW'><style id='yVzxW'><dir id='yVzxW'><q id='yVzxW'></q></dir></style></legend>
                  1. <small id='yVzxW'></small><noframes id='yVzxW'>