• <legend id='F6Gqm'><style id='F6Gqm'><dir id='F6Gqm'><q id='F6Gqm'></q></dir></style></legend>
    • <bdo id='F6Gqm'></bdo><ul id='F6Gqm'></ul>

    <small id='F6Gqm'></small><noframes id='F6Gqm'>

    1. <tfoot id='F6Gqm'></tfoot>

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

        捕捉 Ctrl+C/SIGINT 并在 python 中优雅地退出多进程

        时间:2023-05-26

        <small id='PlXOE'></small><noframes id='PlXOE'>

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

              <bdo id='PlXOE'></bdo><ul id='PlXOE'></ul>

                <legend id='PlXOE'><style id='PlXOE'><dir id='PlXOE'><q id='PlXOE'></q></dir></style></legend>
                  本文介绍了捕捉 Ctrl+C/SIGINT 并在 python 中优雅地退出多进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

                  问题描述

                  限时送ChatGPT账号..

                  如何在多进程 python 程序中捕获 Ctrl+C 并优雅地退出所有进程,我需要该解决方案在 unix 和 windows 上都可以工作.我尝试了以下方法:

                  How do I catch a Ctrl+C in multiprocess python program and exit all processes gracefully, I need the solution to work both on unix and windows. I've tried the following:

                  import multiprocessing
                  import time
                  import signal
                  import sys
                  
                  jobs = []
                  
                  def worker():
                      signal.signal(signal.SIGINT, signal_handler)
                      while(True):
                          time.sleep(1.1234)
                          print "Working..."
                  
                  def signal_handler(signal, frame):
                      print 'You pressed Ctrl+C!'
                      # for p in jobs:
                      #     p.terminate()
                      sys.exit(0)
                  
                  if __name__ == "__main__":
                      for i in range(50):
                          p = multiprocessing.Process(target=worker)
                          jobs.append(p)
                          p.start()
                  

                  它有点工作,但我认为这不是正确的解决方案.

                  And it's kind of working, but I don't think it's the right solution.

                  推荐答案

                  先前接受的解决方案 有竞争条件,但它没有使用 mapasync 函数.

                  The previously accepted solution has race conditions and it does not work with map and async functions.

                  multiprocessing.Pool处理Ctrl+C/SIGINT的正确方法是:

                  1. 在创建进程 Pool 之前让进程忽略 SIGINT.这种方式创建的子进程继承 SIGINT 处理程序.
                  2. 在创建 Pool 后,在父进程中恢复原始 SIGINT 处理程序.
                  3. 使用 map_asyncapply_async 而不是阻塞 mapapply.
                  4. 使用超时等待结果,因为默认阻塞等待忽略所有信号.这是 Python 错误 https://bugs.python.org/issue8296.
                  1. Make the process ignore SIGINT before a process Pool is created. This way created child processes inherit SIGINT handler.
                  2. Restore the original SIGINT handler in the parent process after a Pool has been created.
                  3. Use map_async and apply_async instead of blocking map and apply.
                  4. Wait on the results with timeout because the default blocking waits to ignore all signals. This is Python bug https://bugs.python.org/issue8296.

                  <小时>

                  把它放在一起:


                  Putting it together:

                  #!/bin/env python
                  from __future__ import print_function
                  
                  import multiprocessing
                  import os
                  import signal
                  import time
                  
                  def run_worker(delay):
                      print("In a worker process", os.getpid())
                      time.sleep(delay)
                  
                  def main():
                      print("Initializng 2 workers")
                      original_sigint_handler = signal.signal(signal.SIGINT, signal.SIG_IGN)
                      pool = multiprocessing.Pool(2)
                      signal.signal(signal.SIGINT, original_sigint_handler)
                      try:
                          print("Starting 2 jobs of 5 seconds each")
                          res = pool.map_async(run_worker, [5, 5])
                          print("Waiting for results")
                          res.get(60) # Without the timeout this blocking call ignores all signals.
                      except KeyboardInterrupt:
                          print("Caught KeyboardInterrupt, terminating workers")
                          pool.terminate()
                      else:
                          print("Normal termination")
                          pool.close()
                      pool.join()
                  
                  if __name__ == "__main__":
                      main()
                  

                  正如@YakovShklarov 所指出的,在父进程中忽略信号和取消忽略信号之间有一个时间窗口,在此期间信号可能会丢失.使用 pthread_sigmask 代替在父进程中临时阻止信号的传递可以防止信号丢失,但是在 Python-2 中不可用.

                  As @YakovShklarov noted, there is a window of time between ignoring the signal and unignoring it in the parent process, during which the signal can be lost. Using pthread_sigmask instead to temporarily block the delivery of the signal in the parent process would prevent the signal from being lost, however, it is not available in Python-2.

                  这篇关于捕捉 Ctrl+C/SIGINT 并在 python 中优雅地退出多进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!

                  上一篇:在 python 服务器中的进程之间共享列表 下一篇:多进程和子进程有什么区别?

                  相关文章

                  最新文章

                1. <small id='Y7aid'></small><noframes id='Y7aid'>

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

                    1. <tfoot id='Y7aid'></tfoot>

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