Python:在后台进程中忽略信号

Python:在后台进程中忽略信号,python,multithreading,signals,Python,Multithreading,Signals,我正在创建一个Python程序,它定期调用外部命令。外部命令需要几分钟的时间 需要几秒钟才能完成。我想减少外部命令终止的可能性 为SIGINT添加一个信号处理程序,结果很糟糕。基本上,我希望SIGINT尝试等到命令 在终止Python程序之前执行。问题是,外部的perogram似乎是 同时获取信号,导致其突然结束。我使用外部线程调用该命令,因为 根据本文,signal的Python文档提到只有主线程接收信号。 有人能帮忙吗。 这是我的代码存根。假设外部程序为/bin/sleep: import

我正在创建一个Python程序,它定期调用外部命令。外部命令需要几分钟的时间 需要几秒钟才能完成。我想减少外部命令终止的可能性 为SIGINT添加一个信号处理程序,结果很糟糕。基本上,我希望SIGINT尝试等到命令 在终止Python程序之前执行。问题是,外部的perogram似乎是 同时获取信号,导致其突然结束。我使用外部线程调用该命令,因为 根据本文,signal的Python文档提到只有主线程接收信号。 有人能帮忙吗。 这是我的代码存根。假设外部程序为/bin/sleep:

import sys
import time
import threading
import signal
def sleep():
  import subprocess
  global sleeping
  cmd = ['/bin/sleep', '10000']
  sleeping  = True
  p = subprocess.Popen(cmd)
  p.wait()
  sleeping = False

def sigint_handler(signum, frame):
  if sleeping:
     print 'busy, will terminate shortly'
     while(sleeping): time.sleep(0.5)
     sys.exit(0)
  else:
     print 'clean exit'
     sys.exit(0)

sleeping = False
signal.signal(signal.SIGINT, sigint_handler)
while(1):
  t1 = threading.Thread(target=sleep)
  t1.start()
  time.sleep(500)
预期的行为是,在程序启动后按Ctrl+C N秒将导致 它等待(10000-N)秒,然后退出。发生的情况是程序立即终止


谢谢

问题在于执行新进程时修改信号处理程序的方式。来自POSIX:

通过fork(2)创建的子级继承其父级信号dis的副本
位置。在execve(2)期间,处理过的信号的处理
重置为默认值;忽略信号的处理被保留
不变。
因此,您需要做的是:

  • 忽略SIGINT信号
  • 启动外部程序
  • 根据需要设置SIGINT处理程序
  • 这样,外部程序将忽略SIGINT

    当然,这会留下一个(非常)小的时间窗口,当您的脚本无法响应SIGINT时。但这是你必须忍受的

    例如:

    sleeping = False
    while(1):
        t1 = threading.Thread(target=sleep)
        signal.signal(signal.SIGINT, signal.SIG_IGN)
        t1.start()
        signal.signal(signal.SIGINT, sigint_handler)
        time.sleep(500)
    

    谢谢你,伊塞德夫!很抱歉,我的响应延迟,其他任务优先。您的解决方案看起来应该可以工作,但由于某些原因,派生的进程仍在接收信号。我更新的主循环与你发布的相同。我可能忽略了一些Python特有的复杂性吗?