Avoid race condition with Popen.send_signal

Discussion in 'Python' started by Jérôme, Jan 2, 2012.

  1. Jérôme

    Jérôme Guest

    Hi all.

    When a subprocess is running, it can be sent a signal with the send_signal
    method :

    process = Popen( args)
    process.send_signal(signal.SIGINT)

    If the SIGINT is sent while the process has already finished, an error is
    raised :

    File "/usr/lib/python2.7/subprocess.py", line 1457, in send_signal
    os.kill(self.pid, sig)
    OSError: [Errno 3] Aucun processus de ce type

    To avoid this, I can check that the process is still alive :

    process = Popen( args)
    process.poll()
    if (None == process.returncode):
    process.send_signal(signal.SIGINT)

    It makes safer, but there is still an issue if the process ends between
    poll() and send_signal().

    What is the clean way to avoid this race condition ?

    Should I use try/except to catch the error or is there a more elegant way to
    go ?

    Thanks.

    --
    Jérôme
     
    Jérôme, Jan 2, 2012
    #1
    1. Advertising

  2. Jérôme

    Adam Skutt Guest

    On Jan 2, 6:09 pm, Jérôme <> wrote:
    > Hi all.
    >
    > When a subprocess is running, it can be sent a signal with the send_signal
    > method :
    >
    > process = Popen( args)
    > process.send_signal(signal.SIGINT)
    >
    > If the SIGINT is sent while the process has already finished, an error is
    > raised :
    >
    >   File "/usr/lib/python2.7/subprocess.py", line 1457, in send_signal
    >     os.kill(self.pid, sig)
    > OSError: [Errno 3] Aucun processus de ce type
    >
    > To avoid this, I can check that the process is still alive :
    >
    > process = Popen( args)
    > process.poll()
    > if (None == process.returncode):
    >     process.send_signal(signal.SIGINT)
    >
    > It makes safer, but there is still an issue if the process ends between
    > poll() and send_signal().
    >
    > What is the clean way to avoid this race condition ?


    The fundamental race condition cannot be removed nor avoided. Ideally,
    avoid the need to send the subprocess a signal in the first place. If
    it cannot be avoided, then trap the exception.

    Adam
     
    Adam Skutt, Jan 3, 2012
    #2
    1. Advertising

  3. Am 03.01.2012 02:19, schrieb Adam Skutt:
    > On Jan 2, 6:09 pm, Jérôme<> wrote:
    >> What is the clean way to avoid this race condition ?

    >
    > The fundamental race condition cannot be removed nor avoided. Ideally,
    > avoid the need to send the subprocess a signal in the first place. If
    > it cannot be avoided, then trap the exception.


    Yes, it can be avoided, that's what the default SIGCHLD-handling
    (keeping the process as a zombie until it's explicitly collected by a
    wait*()) is for, which forces the PID not to be reused by the operating
    system until the parent has acknowledged (by actively calling wait*())
    that the child has terminated.

    --
    --- Heiko.
     
    Heiko Wundram, Jan 3, 2012
    #3
  4. Jérôme

    Adam Skutt Guest

    On Jan 3, 7:31 am, Heiko Wundram <> wrote:
    > Am 03.01.2012 02:19, schrieb Adam Skutt:
    >
    > > On Jan 2, 6:09 pm, Jérôme<>  wrote:
    > >> What is the clean way to avoid this race condition ?

    >
    > > The fundamental race condition cannot be removed nor avoided. Ideally,
    > > avoid the need to send the subprocess a signal in the first place.  If
    > > it cannot be avoided, then trap the exception.

    >
    > Yes, it can be avoided, that's what the default SIGCHLD-handling
    > (keeping the process as a zombie until it's explicitly collected by a
    > wait*()) is for, which forces the PID not to be reused by the operating
    > system until the parent has acknowledged (by actively calling wait*())
    > that the child has terminated.


    No, you still can see ESRCH when sending signals to a zombie process.
    Code that sends signals to child processes via kill(2) must be
    prepared for the call to fail at anytime since the process can die at
    anytime. It can't handle the signal, so it's treated as if it doesn't
    exist by kill(2) in this case. However, you don't have to worry about
    sending the signal to the wrong process.

    Adam
     
    Adam Skutt, Jan 3, 2012
    #4
  5. Am 03.01.2012 14:40, schrieb Adam Skutt:
    > On Jan 3, 7:31 am, Heiko Wundram<> wrote:
    >> Yes, it can be avoided, that's what the default SIGCHLD-handling
    >> (keeping the process as a zombie until it's explicitly collected by a
    >> wait*()) is for, which forces the PID not to be reused by the operating
    >> system until the parent has acknowledged (by actively calling wait*())
    >> that the child has terminated.

    >
    > No, you still can see ESRCH when sending signals to a zombie process.
    > Code that sends signals to child processes via kill(2) must be
    > prepared for the call to fail at anytime since the process can die at
    > anytime. It can't handle the signal, so it's treated as if it doesn't
    > exist by kill(2) in this case. However, you don't have to worry about
    > sending the signal to the wrong process.


    Getting an error on kill (which you can catch) is not about the race
    that the posters were speculating about (i.e., sending the signal to the
    wrong process), and that's what I was trying to put straight. The only
    advice that I wanted to give is:

    1) before calling wait to collect the child, call kill as much as you
    like, and in case it errors, ignore that,

    2) after calling wait, never, ever kill, and you don't need to, because
    you already know the process is gone.

    There's no race possibility in this, _except_ if you alter handling of
    SIGCHLD away from the default (i.e., to autocollect children), in which
    case you have the possibility of a race and shooting down unrelated
    processes (which the discussion was about).

    --
    --- Heiko.
     
    Heiko Wundram, Jan 3, 2012
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. jimjim

    race condition question

    jimjim, Nov 1, 2003, in forum: Java
    Replies:
    6
    Views:
    417
    jimjim
    Nov 2, 2003
  2. Replies:
    1
    Views:
    350
    Kevin Spencer
    Aug 7, 2006
  3. Replies:
    3
    Views:
    742
  4. Cameron Simpson
    Replies:
    14
    Views:
    408
    Jérôme
    Jan 3, 2012
  5. Guillaume Marcais

    net-ssh send_signal

    Guillaume Marcais, Oct 22, 2005, in forum: Ruby
    Replies:
    5
    Views:
    181
    Jamis Buck
    Oct 22, 2005
Loading...

Share This Page