我可以使用Python异常来处理守护进程的SIGHUP信号吗?
我正在用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 个回答
2
你应该抛出一个 fsync_config_exception
的实例,而不是类本身。也就是说,要用它的 __init__()
方法来创建一个对象。
不过,我不建议你以这种方式抛出异步异常。这样做很难保证异常只在可以正确处理的时候被抛出。而且,这种做法也不太好,因为在Python解释器中,你无法中断阻塞的C扩展调用……(但这对你来说可能不是问题?)
在信号处理程序中,我会(简单说一下细节,不确定这是否适合你的情况):
- 设置状态,标记当前的迭代已经被中断——用这个来判断是否需要进行特殊的清理工作
- 在信号处理程序中,终止你正在等待的进程
- 在等待之后再加一个条件检查,看看进程是否是被信号杀掉的(同时检查状态变量,看看是否收到了SIGHUP信号)
- 根据SIGHUP信号做你需要做的事情