2015-12-03 116 views
3

添加信號處理程序,例如如何註冊子進程的信號處理程序?

#!/usr/bin/python 

import subprocess as sp 
import signal 
import time 

def child_handler(sig, frame): 
    print("SIGINT child received") 

def handler(sig, frame): 
    print("SIGINT received") 

def preexec(): 
    print("entering preexec") 
    signal.signal(signal.SIGINT, child_handler) 
    #signal.signal(signal.SIGINT, signal.SIG_IGN) 
    print("leaving preexec") 

def signal_sending(): 
    signal.signal(signal.SIGINT, handler) 
    p = sp.check_call(["bash", "process.sh"], preexec_fn=preexec) 

if __name__ == "__main__": 
    signal_sending() 

process.sh

#!/bin/sh 

i=0 

while [ 1 ]; do 
sleep 0.1; 
echo $i 
i=$((i + 1)) 
done 

不起作用,因爲按Ctrlç中斷子進程(僅SIGINT received打印),但兩者SIGINT receivedSIGINT child received應打印和孩子繼續跑步。

添加signal.SIG_IGN離開孩子也不放過,但還不夠,因爲我需要寫爲孩子定製的處理程序。

我不在乎,如果我有使用Python 2.7或3.x版到acchieve這一點。我正在使用Linux 4.3。

回答

1

bash過程取代了分叉python過程,因此它不能運行Python回調。 SIG_IGN適用於SIGINT,因爲它在exec()電話中生存。

如果你想要一些Python代碼運行時Ctrl + C被按下;把它放在handler()(父母的信號處理程序)。或者在bash中捕獲相應的信號,然後在process.sh的信號上運行python子進程。

+0

啊,我只是要求對信號處理的更好的文檔在http://bugs.python.org/issue25787。任何想法如何防止接收子進程的子進程的SIGINT?我很忙於'apt-get',它產生'dpkg',它自己產生像'gpgv'這樣的進程,並且因爲SIGINT被兒童的孩子接收而中止。 –

+0

shell中的Ctrl + C將SIGINT發送到前臺進程組(當前管道)中的所有進程。通過'preexec_fn = os.setpgrp'來創建一個新的進程組,以避免信號傳播給子進程(及其子進程)。 – jfs

+0

指定'preexec_fn = os.setpgrp'使終端('侏儒-terminal'和'xterm')無響應期待'其在父進程處理(在我的註冊自定義處理程序)SIGINT'。 –

相關問題