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

我正在创建一个Python程序,该程序会定期调用外部命令.外部命令需要一些秒完成.我想减少外部命令终止的可能性通过为SIGINT添加信号处理程序来严重降低性能.基本上,我希望SIGINT尝试等到命令在终止Python程序之前执行....

我正在创建一个Python程序,该程序会定期调用外部命令.外部命令需要一些
秒完成.我想减少外部命令终止的可能性
通过为SIGINT添加信号处理程序来严重降低性能.基本上,我希望SIGINT尝试等到命令
在终止Python程序之前执行.问题是,外部Perogram似乎是
也获得SIGINT,导致其突然结束.我正在使用外部线程调用命令,因为
根据http://docs.python.org/2/library/signal.html,有关信号的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)

预期的行为是程序启动后N秒钟按Ctrl C将导致
它等待(10000-N)秒,然后退出.发生的情况是程序立即终止.

谢谢!

解决方法:

问题是执行新进程时修改信号处理程序的方式.从POSIX:

A child created via fork(2) inherits a copy of its parent's signal dis‐
positions.  During an execve(2), the dispositions  of  handled  signals
are  reset to the default; the dispositions of ignored signals are left
unchanged.

因此,您需要做的是:

>忽略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:忽略后台进程中的信号

基础教程推荐