2014-10-07 68 views
1

我有,我在类似的方式创建multiprocessing.Process对象的几个新实例从一个主要处理的Python应用程序:在Python中注册信号处理程序的正确方法是什么?

self.my_proc = Process(name='foo', target=self.bar, args=(self.some_var,)) 
    self.my_proc.daemon = True 
    self.my_proc.start() 
    ... 

    @staticmethod 
    def bar(some_var): 
     while True: 
      do stuff forever 

我注意到,如果我注册的主要处理的信号处理程序在我生成子进程之前,信号事件会导致每个产生的进程调用信号处理程序。如果我在产生子进程后注册信号处理程序,那么信号事件只会导致父进程调用信号处理程序。

我真的只想要主(父)进程接收信号处理程序回调,因为它是清理所有子进程的进程。所以我的程序按我需要的方式工作。但我担心的是,在多进程Python应用程序中处理信号有更好的(正确的)方法。在那儿?

回答

1

这是什么与Python一样。它反映了UNIX(Linux)实现信号及其在进程创建子进程时的行为(使用系统调用fork)。以下是说明您已注意到的行为的手册中的一段引言:

通过fork(2)创建的子级继承其父级信号处置的副本。
execve(2)期间,处理信号的设置被重置为默认值; 忽略信号的配置保持不变。

+0

我相信POSIX'fork'实际上并没有记录信号处理程序会发生什么;可以复制它们,将它们重置为默认值或几乎任何其他值。当然,无论如何,你不能在portable和exec之间移植任何不是异步信号安全的东西,所以这对于便携代码来说并不重要...... – abarnert 2014-10-07 18:46:51

+0

另外,值得注意的是,最近的3.x给出了你至少可以采取更多的方式来控制2.x没有的东西:你可以'fork + exec'子进程而不是'fork',你可以执行“fork from a thread”加'pthread_sigmask'欺骗一些Web服务器在某些* nix平台上使用。 – abarnert 2014-10-07 18:47:23

+0

@abarnert在你的评论后,我总是会得到额外的阅读:)并非我在抱怨。 – isedev 2014-10-07 18:49:34

0

如果它在你的主要过程方便(因为它似乎是),如果你只关心抓住SIGINT,我宁愿赶上一个KeyboardInterrupt而不是安装一个信号处理程序:

@staticmethod 
def bar(): 
    try: 
     while True: 
      # do stuff forever 
      pass 
    except KeyboardInterrupt: 
     # Tell subprocesses to shutdown gracefully 
     pass 
相关问题