2014-10-07 112 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 
相關問題