Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!news.albasani.net!news2.arglkargh.de!feeder.erje.net!1.eu.feeder.erje.net!bcyclone05.am1.xlned.com!bcyclone05.am1.xlned.com!lightspeed.eweka.nl!lightspeed.eweka.nl!newsfeed.xs4all.nl!newsfeed3a.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'essentially': 0.04; '(b)': 0.07; 'cleanup': 0.07; 'exit': 0.07; 'closed.': 0.09; 'events.': 0.09; 'exits': 0.09; 'function),': 0.09; 'loop.': 0.09; 'returns,': 0.09; '(at': 0.13; 'file,': 0.15; '>to': 0.16; 'child.': 0.16; 'cleans': 0.16; 'from:addr:cs': 0.16; 'from:addr:zip.com.au': 0.16; 'from:name:cameron simpson': 0.16; 'message-id:@cskk.homeip.net': 0.16; 'poll': 0.16; 'processes.': 0.16; 'reasonable.': 0.16; 'received:211.29': 0.16; 'received:211.29.132': 0.16; 'received:cskk.homeip.net': 0.16; 'received:homeip.net': 0.16; 'received:optusnet.com.au': 0.16; 'received:syd.optusnet.com.au': 0.16; 'simpson': 0.16; 'subprocess': 0.16; 'subprocess,': 0.16; 'terminated.': 0.16; 'thread.': 0.16; 'uncommon': 0.16; 'wrote:': 0.16; 'programmer': 0.18; 'library': 0.20; '(the': 0.22; '(a)': 0.22; 'latter': 0.22; 'cheers,': 0.24; 'header:In-Reply-To:1': 0.24; 'header:User- Agent:1': 0.26; 'collecting': 0.27; 'once.': 0.29; 'code:': 0.29; 'putting': 0.31; 'task': 0.31; 'run': 0.32; 'table': 0.32; 'instances': 0.33; 'received:com.au': 0.33; 'open': 0.33; 'everyone': 0.34; 'this?': 0.34; 'could': 0.35; 'to:addr:python- list': 0.35; 'tasks': 0.35; 'list': 0.35; "isn't": 0.35; 'but': 0.36; 'there': 0.36; 'child': 0.36; 'subject:: ': 0.37; 'charset :us-ascii': 0.37; 'list.': 0.37; 'instead': 0.38; 'associated': 0.38; 'busy': 0.38; 'moment': 0.38; 'someone': 0.38; 'wanted': 0.39; 'things': 0.39; 'whatever': 0.39; 'to:addr:python.org': 0.39; 'resources': 0.39; 'some': 0.40; 'content- disposition:inline': 0.60; 'your': 0.60; 'simple': 0.61; 'documents': 0.61; 'effective': 0.62; 'more': 0.62; 'minutes': 0.64; 'cameron': 0.66; 'receive': 0.71; 'walk': 0.72; '>with': 0.84; 'cecil': 0.84; 'dispatched': 0.84; 'immediate.': 0.84; 'spawned': 0.84; 'westerhof': 0.84; 'you.)': 0.84; 'subject:Best': 0.91 Date: Mon, 1 Jun 2015 11:03:01 +1000 From: Cameron Simpson To: python-list@python.org Subject: Re: Best way to prevent zombie processes MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Disposition: inline In-Reply-To: <87vbf8l9e7.fsf@Equus.decebal.nl> User-Agent: Mutt/1.5.23 (2014-03-12) References: <87vbf8l9e7.fsf@Equus.decebal.nl> X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=F6tuKMRN c=1 sm=1 tr=0 a=rgDbx50tNA2z7xLXQOoruw==:117 a=rgDbx50tNA2z7xLXQOoruw==:17 a=ZtCCktOnAAAA:8 a=PO7r1zJSAAAA:8 a=J0QyKEt1u0cA:10 a=kj9zAlcOel0A:10 a=vrnE16BAAAAA:8 a=XAFQembCKUMA:10 a=GAn6pz5ktNeg41HamI4A:9 a=CjuIK1q_8ugA:10 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 50 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1433125553 news.xs4all.nl 2835 [2001:888:2000:d::a6]:34158 X-Complaints-To: abuse@xs4all.nl X-Received-Body-CRC: 773103694 X-Received-Bytes: 6225 Xref: csiph.com comp.lang.python:91607 On 31May2015 23:33, Cecil Westerhof wrote: >At the moment I have the following code: > os.chdir(directory) > for document in documents: > subprocess.Popen(['evince', document]) > >With this I can open several documents at once. But there is no way to >know when those documents are going to be closed. This could/will lead >to zombie processes. (I run it on Linux.) What is the best solution to >circumvent this? The standard trick is to make the process a grandchild instead of a child. Fork, kick off subprocess, exit (the forked child). But provided you will collect the children eventually then zombies are only untidy, not very resource wasteful. They are essentially just slots in the process table left around so that exit status can be collected; the resources associated with the full process (memory, open file, etc) have already been freed. >I was thinking about putting all Popen instances in a list. And then >every five minutes walk through the list and check with poll if the >process has terminated. If it has it can be released from the list. >Of-course I need to synchronise those events. Is that a good way to do >it? It is reasonable. Alternatively, and more responsively, you could have a process collection Thread. It would loop indefinitely, calling os.wait(). That will block until a child process exits (any of them), so it is not a busy loop. When wait() returns, look up the pid in your list of dispatched subprocess children and do whatever cleanup you intend. (If it is just zombies, the os.wait() cleans that part for you.) One thing you do need to keep in mind with such a task is that it will os.wait() _all_ child processes. If there are other children which exit, not spawned by your specific calls (earlier children or children made by some library function), you must be prepared to receive pids which (a) are not in your list of "evince" etc tasks and (b) to be collecting pids which other subsystems might have wanted to collect themselves. The latter is uncommon (at least, uncommon for such things to occur and you the programmer to be unaware of them). Anyway, that is simple and effective and immediate. Cheers, Cameron Simpson If everyone is thinking alike, then someone isn't thinking. - Patton