Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder4.news.weretis.net!storethat.news.telefonica.de!telefonica.de!news.panservice.it!feed.xsnews.nl!border01.ams.xsnews.nl!feeder01.ams.xsnews.nl!abp001.ams.xsnews.nl!frontend-F10-09.ams.news.kpn.nl From: Cecil Westerhof Newsgroups: comp.lang.python Subject: Re: Best way to prevent zombie processes Organization: Decebal Computing References: <87vbf8l9e7.fsf@Equus.decebal.nl> <871thvlj3e.fsf@Equus.decebal.nl> X-Face: "(y8cC@tg_12{">GF'UXTW]FHI2wMiZNrnf'1EFQ&O#$m:f#O7+7}kR,v+Pti8=Vi/Z"g^?b"E X-Homepage: http://www.decebal.nl/ Date: Mon, 01 Jun 2015 15:03:52 +0200 Message-ID: <87wpznk2br.fsf@Equus.decebal.nl> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux) Cancel-Lock: sha1:ABIOzUtEC/LS2no5VjFHV4Y7UAI= MIME-Version: 1.0 Content-Type: text/plain Lines: 92 NNTP-Posting-Host: 81.207.62.244 X-Trace: 1433165395 news.kpn.nl 20900 81.207.62.244@kpn/81.207.62.244:36827 Xref: csiph.com comp.lang.python:91673 Op Monday 1 Jun 2015 14:16 CEST schreef Cecil Westerhof: > Op Sunday 31 May 2015 23:33 CEST schreef Cecil Westerhof: > >> 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? >> >> 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? > > With some investigation I decided on something completely different. > > I made a class: > import os > import subprocess > > from os.path import expanduser > from threading import Thread > > class DocumentsToShow: > def show_documents(self): > if self._desktop != -1: > subprocess.check_call(['wmctrl', '-s', str(self._desktop - 1)]) > os.chdir(self._directory) > for document in self._documents: > Popen_without_zombie(['evince', document]) > > def __init__(self, name, desktop, directory, documents): > '''Initialise the class''' > > self._name = name > self._desktop = desktop > self._directory = expanduser(directory) > self._documents = documents > > And this class uses the following function: > def Popen_without_zombie(command): > p = subprocess.Popen(command) > Thread(target = p.wait).start() > > The class takes a name for the collection, which desktop to display > it on, the directory that contains the documents and a list of > documents. With show_documents they are displayed. > > How about this way of solving it? > > > About the improvement of the class. Now it is always evince that is > used to open a document. But it would be nice if it was a little > less picky. What is the preferred way to solve this? - Defining a > set the user can choose from. - Making it a string parameter and > expecting the user to know what he is doing. I let the user give the command to open the documents, but check if the command exists: class DocumentsToShow: def show_documents(self): if self._desktop != -1: subprocess.check_call(['wmctrl', '-s', str(self._desktop - 1)]) os.chdir(self._directory) for document in self._documents: Popen_without_zombie([self._command, document]) def __init__(self, name, desktop, command, directory, documents): '''Initialise the class''' try: subprocess.check_call(['which', command]) except subprocess.CalledProcessError: raise ValueError('Command \'{0}\' is not known'.format(command)) self._name = name self._desktop = desktop self._command = command self._directory = expanduser(directory) self._documents = documents -- Cecil Westerhof Senior Software Engineer LinkedIn: http://www.linkedin.com/in/cecilwesterhof