Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #90955 > unrolled thread

subprocess.Popen zombie

Started byRobin Becker <robin@reportlab.com>
First post2015-05-20 14:16 +0100
Last post2015-05-21 08:13 -0600
Articles 6 — 5 participants

Back to article view | Back to comp.lang.python


Contents

  subprocess.Popen zombie Robin Becker <robin@reportlab.com> - 2015-05-20 14:16 +0100
    Re: subprocess.Popen zombie Cecil Westerhof <Cecil@decebal.nl> - 2015-05-20 16:48 +0200
    Re: subprocess.Popen zombie Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> - 2015-05-20 17:42 +0200
      Re: subprocess.Popen zombie Robin Becker <robin@reportlab.com> - 2015-05-20 17:44 +0100
        Re: subprocess.Popen zombie Thomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> - 2015-05-21 08:35 +0200
          Re: subprocess.Popen zombie Ian Kelly <ian.g.kelly@gmail.com> - 2015-05-21 08:13 -0600

#90955 — subprocess.Popen zombie

FromRobin Becker <robin@reportlab.com>
Date2015-05-20 14:16 +0100
Subjectsubprocess.Popen zombie
Message-ID<mailman.170.1432127818.17265.python-list@python.org>
As part of a long running PyQT process running as a window app in Arch linux I 
needed an alert sound, I decided to use the beep command and the app code then 
looked like

pid = Popen(['/home/robin/bin/mybeep', '-r3', '-f750', '-l100', '-d75']).pid

the mybeep script handles module loading if required etc etc.

Anyhow, this works with one slight oddity. When this code is executed it works 
fine, but leaves behind a single zombie process, when next executed the zombie 
disappears and a new zombie replaces it.

Is this because I'm not waiting? Does the process module reap previous commands 
in some way? The code I used to use with os.spawnl was even worse in leaving 
zombies around. I suppose I needed to keep a record of all the pid's and wait on 
them at some convenient time. The subprocess version appears to be doing that 
for me somehow.


*NB* I did try PyQT's qApp.beep(), but it seemed to work only on windows.
-- 
Robin Becker

[toc] | [next] | [standalone]


#90957

FromCecil Westerhof <Cecil@decebal.nl>
Date2015-05-20 16:48 +0200
Message-ID<87vbfnqp8p.fsf@Equus.decebal.nl>
In reply to#90955
Op Wednesday 20 May 2015 15:16 CEST schreef Robin Becker:

> As part of a long running PyQT process running as a window app in
> Arch linux I needed an alert sound, I decided to use the beep
> command and the app code then looked like
>
> pid = Popen(['/home/robin/bin/mybeep', '-r3', '-f750', '-l100',
> '-d75']).pid
>
> the mybeep script handles module loading if required etc etc.
>
> Anyhow, this works with one slight oddity. When this code is
> executed it works fine, but leaves behind a single zombie process,
> when next executed the zombie disappears and a new zombie replaces
> it.
>
> Is this because I'm not waiting? Does the process module reap

Yes, you should do a:
     pid.wait()

Should not be a problem, because the program you are calling takes
very little time.

-- 
Cecil Westerhof
Senior Software Engineer
LinkedIn: http://www.linkedin.com/in/cecilwesterhof

[toc] | [prev] | [next] | [standalone]


#90961

FromAlain Ketterlin <alain@universite-de-strasbourg.fr.invalid>
Date2015-05-20 17:42 +0200
Message-ID<87bnhfqmr4.fsf@universite-de-strasbourg.fr.invalid>
In reply to#90955
Robin Becker <robin@reportlab.com> writes:

> As part of a long running PyQT process running as a window app in Arch
> linux I needed an alert sound, I decided to use the beep command and
> the app code then looked like
>
> pid = Popen(['/home/robin/bin/mybeep', '-r3', '-f750', '-l100', '-d75']).pid
>
> the mybeep script handles module loading if required etc etc.
>
> Anyhow, this works with one slight oddity. When this code is executed
> it works fine, but leaves behind a single zombie process, when next
> executed the zombie disappears and a new zombie replaces it.
>
> Is this because I'm not waiting?

Yes, all processes will stay zombies until being wait()-ed for by their
parent process. This means: either you use call(...) which doesn't
return until the child process has finished, or you keep the Popen
object around and call wait() at an appropriate time.

> Does the process module reap previous commands in some way?

No.

> The code I used to use with os.spawnl was even worse in leaving
> zombies around.

For the same reason (os.wait() and os.waitpid() let you ... wait for
child-processes).

> I suppose I needed to keep a record of all the pid's and wait on them
> at some convenient time.

Yes.

> The subprocess version appears to be doing that for me somehow.

Not sure what you mean. You have to do the bookkeeping yourself.

(But, does beep really take so much time that you can't just call() it?)

-- Alain.

[toc] | [prev] | [next] | [standalone]


#90969

FromRobin Becker <robin@reportlab.com>
Date2015-05-20 17:44 +0100
Message-ID<mailman.177.1432140299.17265.python-list@python.org>
In reply to#90961
On 20/05/2015 16:42, Alain Ketterlin wrote:
> Robin Becker <robin@reportlab.com> writes:
.............
>> The code I used to use with os.spawnl was even worse in leaving
>> zombies around.
>
> For the same reason (os.wait() and os.waitpid() let you ... wait for
> child-processes).
>
>> I suppose I needed to keep a record of all the pid's and wait on them
>> at some convenient time.
>
> Yes.
>
>> The subprocess version appears to be doing that for me somehow.
>
> Not sure what you mean. You have to do the bookkeeping yourself.
It seems there is some notion of book keeping in subprocess.py
Popen instances have a __del__ method which records  un-norwegian live instances 
in a module global _active

if self.returncode is None and _active is not None:
     # Child is still running, keep us alive until we can wait on it.
    _active.append(self)


when another Popen is created there's a call to _cleanup which processes that 
list and reaps those that can be raptured.


>
> (But, does beep really take so much time that you can't just call() it?)
>
not really, it's just normal to keep event routines short; the routine which 
beeps is after detection of the cat's entrance into the house and various 
recognition schemes have pronounced intruder :)

Probably should all have gone into a separate thread, but I dislike threaded 
code and I would probably get into trouble with the PyQT event loop.

> -- Alain.
>


-- 
Robin Becker

[toc] | [prev] | [next] | [standalone]


#90998

FromThomas Rachel <nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de>
Date2015-05-21 08:35 +0200
Message-ID<mjjuc5$1ft$1@r01.glglgl.de>
In reply to#90969
Am 20.05.2015 um 18:44 schrieb Robin Becker:

> not really, it's just normal to keep event routines short; the routine
> which beeps is after detection of the cat's entrance into the house and
> various recognition schemes have pronounced intruder :)

You could add a timed "cleanup" routine which .wait()s after a certain 
time (250 ms or so).

Or even better, which .poll()s and re-schedules itself if the process 
still runs.


Thomas

[toc] | [prev] | [next] | [standalone]


#91008

FromIan Kelly <ian.g.kelly@gmail.com>
Date2015-05-21 08:13 -0600
Message-ID<mailman.199.1432217627.17265.python-list@python.org>
In reply to#90998

[Multipart message — attachments visible in raw view] — view raw

On May 21, 2015 12:41 AM, "Thomas Rachel" <
nutznetz-0c1b6768-bfa9-48d5-a470-7603bd3aa915@spamschutz.glglgl.de> wrote:
>
> Am 20.05.2015 um 18:44 schrieb Robin Becker:
>
>> not really, it's just normal to keep event routines short; the routine
>> which beeps is after detection of the cat's entrance into the house and
>> various recognition schemes have pronounced intruder :)
>
>
> You could add a timed "cleanup" routine which .wait()s after a certain
time (250 ms or so).
>
> Or even better, which .poll()s and re-schedules itself if the process
still runs.

Or just:

    Thread(target=p.wait).start()

And then you can forget all about it.

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web