How to stop python from propagating signals to subprocesses?

前端 未结 5 1622
情歌与酒
情歌与酒 2020-12-17 08:51

I\'m using python to manage some simulations. I build the parameters and run the program using:

pipe = open(\'/dev/null\', \'w\')
pid = subprocess.Popen(shle         


        
5条回答
  •  青春惊慌失措
    2020-12-17 09:34

    This can indeed be done using ctypes. I wouldn't really recommend this solution, but I was interested enough to cook something up, so I thought I would share it.

    parent.py

    #!/usr/bin/python
    
    from ctypes import *
    import signal
    import subprocess
    import sys
    import time
    
    # Get the size of the array used to
    # represent the signal mask
    SIGSET_NWORDS = 1024 / (8 * sizeof(c_ulong))
    
    # Define the sigset_t structure
    class SIGSET(Structure):
        _fields_ = [
            ('val', c_ulong * SIGSET_NWORDS)
        ]
    
    # Create a new sigset_t to mask out SIGINT
    sigs = (c_ulong * SIGSET_NWORDS)()
    sigs[0] = 2 ** (signal.SIGINT - 1)
    mask = SIGSET(sigs)
    
    libc = CDLL('libc.so.6')
    
    def handle(sig, _):
        if sig == signal.SIGINT:
            print("SIGINT from parent!")
    
    def disable_sig():
        '''Mask the SIGINT in the child process'''
        SIG_BLOCK = 0
        libc.sigprocmask(SIG_BLOCK, pointer(mask), 0)
    
    # Set up the parent's signal handler
    signal.signal(signal.SIGINT, handle)
    
    # Call the child process
    pid = subprocess.Popen("./child.py", stdout=sys.stdout, stderr=sys.stdin, preexec_fn=disable_sig)
    
    while (1):
        time.sleep(1)
    

    child.py

    #!/usr/bin/python
    import time
    import signal
    
    def handle(sig, _):
        if sig == signal.SIGINT:
            print("SIGINT from child!")
    
    signal.signal(signal.SIGINT, handle)
    while (1):
        time.sleep(1)
    

    Note that this makes a bunch of assumptions about various libc structures and as such, is probably quite fragile. When running, you won't see the message "SIGINT from child!" printed. However, if you comment out the call to sigprocmask, then you will. Seems to do the job :)

提交回复
热议问题