我可以使用Python Exceptions来处理守护进程的SIGHUP信号的后果吗?

时间:2011-01-31 19:01:04

标签: python exception signals daemon

我正在python中编写一个简单的小文件同步守护进程,以在主机和辅助机器之间实现同步文件系统。大部分繁重的工作都是通过rsync完成的。

在初级端,它会定期调用rsync并在重复之前休眠几秒钟。在次要方面,它使用subprocess.Popen()生成rsyncd并执行.wait()直到它退出。但是我想用SIGHUP触发守护进程的重新配置。我想知道处理清理的最佳方法是什么。

我最初的想法是让信号处理程序引发一个可以触发清理的异常:

def signal_handler(signum, frame):
    raise fsync_config_exception

rsync_args = [rsync_binary, "--daemon", "--no-detach", "--config=%s" % (config.name) ]
p = subprocess.Popen(rsync_args)
try:
    p.wait()
    if p.returncode != 0:
        print "failed to spawn rsyncd"
        return False
except fsync_config_exception:
    print "spawn_and_monitor_rsyncd: config exceptions"
except:
    (type, value, tb) = sys.exc_info()
    print "we got %s with %s instead" % (type, value)

但是我得到了:

we got <type 'exceptions.TypeError'> with __init__() takes exactly 2 arguments (1 given) instead

而不是预期的fsync_config_exception。有没有人对这类问题的最佳方法有任何建议?我是否通过尝试从信号环境中提升它们来隐瞒滥用例外?

1 个答案:

答案 0 :(得分:2)

您应该引发fsync_config_exception实例,而不是类。 (使用其__init__()签名实例化)

但是,我不建议以这种方式引发异步异常。您将很难保证只有在可以正确处理的情况下才会引发异常。它也不是一个习惯的好模式,因为你不能在Python解释器上下文中断阻塞C扩展调用....(但这对你来说可能不是问题?)

在信号处理程序中,我会(掩盖细节而不知道这是否适合您的情况):

  • 设置状态,注意当前迭代已被中断 - 使用此标记来标记是否按顺序进行特殊清理
  • 在信号处理程序中,终止您正在等待的进程
  • 在等待之后添加另一个条件检查以查看该进程是否被信号杀死(另外检查状态变量,注意是否收到了SIGHUP)
  • 执行响应SIGHUP所需的操作