Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!gegeweb.org!de-l.enfer-du-nord.net!feeder2.enfer-du-nord.net!feeder.news-service.com!news2.euro.net!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.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'else:': 0.03; 'exits': 0.07; 'subject:process': 0.07; 'terminated': 0.07; 'wrapper': 0.07; '%s"': 0.09; 'attribute.': 0.09; 'finished,': 0.09; 'indicates': 0.09; 'normally,': 0.09; 'object?': 0.09; 'subprocess': 0.09; 'output': 0.10; 'error:': 0.12; 'def': 0.15; 'intermediate': 0.15; 'method.': 0.15; '-1:': 0.16; '127': 0.16; 'cc:name:python list': 0.16; 'coded': 0.16; 'command)': 0.16; 'failing': 0.16; 'getting,': 0.16; 'picks': 0.16; 'process?': 0.16; 'returncode': 0.16; 'stderr': 0.16; 'subject: \n ': 0.16; 'subject:() ': 0.16; 'subject:bit': 0.16; '\xc2\xa0i': 0.16; '\xc2\xa0if': 0.16; 'cc:addr:python-list': 0.16; 'this:': 0.16; 'wrote:': 0.16; 'modified': 0.18; 'subject:skip:s 10': 0.18; 'received:74.125.82.174': 0.19; 'received:mail- wy0-f174.google.com': 0.19; 'memory': 0.21; 'trying': 0.21; 'options.': 0.21; 'cc:2**0': 0.22; 'header:In-Reply-To:1': 0.22; 'compiled': 0.23; 'loop,': 0.23; 'sep': 0.23; 'pm,': 0.24; 'sender:addr:gmail.com': 0.25; 'says': 0.25; 'code': 0.25; 'guess': 0.26; 'code.': 0.26; "i'm": 0.27; 'code,': 0.28; 'skip:p 30': 0.28; 'bit': 0.28; 'problem': 0.28; 'correct': 0.28; 'condition.': 0.29; 'exit': 0.29; 'explicitly': 0.29; 'looks': 0.29; 'message-id:@mail.gmail.com': 0.29; 'print': 0.29; 'script': 0.29; 'cc:addr:python.org': 0.30; '-1,': 0.30; 'complete,': 0.30; 'returns,': 0.30; 'reporting': 0.31; 'url:library': 0.31; 'changes': 0.31; 'error': 0.32; 'version': 0.32; 'hi,': 0.32; 'does': 0.32; 'sort': 0.33; 'there': 0.33; 'instead': 0.33; "i've": 0.34; 'however,': 0.34; 'someone': 0.34; 'but,': 0.34; 'test': 0.34; 'examine': 0.34; 'here,': 0.35; 'running': 0.35; 'anything': 0.36; 'url:python': 0.36; 'fri,': 0.36; 'question': 0.36; 'none': 0.37; 'passed': 0.37; 'received:74.125.82': 0.38; 'cases,': 0.38; 'signal': 0.38; 'some': 0.38; 'received:google.com': 0.38; 'url:org': 0.38; 'should': 0.38; 'subject:: ': 0.39; 'returned': 0.39; 'sets': 0.39; 'getting': 0.39; 'url:docs': 0.39; 'help': 0.39; 'received:74.125': 0.39; 'called': 0.40; 'subject:from': 0.40; "it's": 0.40; 'where': 0.40; 'happens': 0.40; 'thinking': 0.40; 'more': 0.60; 'your': 0.61; 'closed': 0.62; 'waiting': 0.63; 'further': 0.64; 'here': 0.65; 'ever': 0.65; 'here.': 0.66; 'race': 0.77; 'codes.': 0.84; 'running,': 0.84; 'unaware': 0.84; 'out...': 0.91; 'unclear': 0.91; 'killed': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=mime-version:sender:in-reply-to:references:from:date :x-google-sender-auth:message-id:subject:to:cc:content-type :content-transfer-encoding; bh=stlCN7vFm2gj+hSqHYnaYI6jQejlVs4g/NPKYK89hg4=; b=s1ESF/4bTZxcYmq3ItgrvWBH8MDQQhk/w9pUS1jKXIKwxlRPdcCT9VS5rZpIL1fGS1 YcVqYxGM+FYlP2Mo8aGzAvoP7P6xg7Z84NWgylHCDPIk1P77xdwDl3rBBEi9dlvFrHD4 4aVKNpYG6NKCc+6wPamgAYL75GG14nvSxFKk4= MIME-Version: 1.0 Sender: kushal.kumaran@gmail.com In-Reply-To: References: From: Kushal Kumaran Date: Sat, 10 Sep 2011 14:49:08 +0530 X-Google-Sender-Auth: jXI2AaNHJ0r9M8wasUBKgtGD4Z0 Subject: Re: A bit of a boggle about subprocess.poll() and the codes it receives from a process To: J Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Cc: Python List X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 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: 122 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1315646370 news.xs4all.nl 2549 [2001:888:2000:d::a6]:50597 X-Complaints-To: abuse@xs4all.nl Xref: x330-a1.tempe.blueboxinc.net comp.lang.python:13056 On Fri, Sep 9, 2011 at 11:02 PM, J wrote: > Hi, > I need a bit of help sorting this out... > I have a memory test script that is a bit of compiled C. =C2=A0The test i= tself > can only ever return a 0 or 1 exit code, this is explicitly coded and the= re > are no other options. > I also have a wrapper test script that calls the C program that should al= so > only return 0 or 1 on completion. > The problem i'm encountering, however, involves the return code when > subprocess.poll() is called against the running memory test process. =C2= =A0The > current code in my wrapper program looks like this: > def run_processes(self, number, command): > =C2=A0 =C2=A0 =C2=A0 =C2=A0 passed =3D True > =C2=A0 =C2=A0 =C2=A0 =C2=A0 pipe =3D [] > =C2=A0 =C2=A0 =C2=A0 =C2=A0 for i in range(number): > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 pipe.append(self._command(comma= nd)) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 print "Started: process %u pid = %u: %s" % (i, pipe[i].pid, > command) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 sys.stdout.flush() > =C2=A0 =C2=A0 =C2=A0 =C2=A0 waiting =3D True > =C2=A0 =C2=A0 =C2=A0 =C2=A0 while waiting: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 waiting =3D False > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 for i in range(number): > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if pipe[i]: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 lin= e =3D pipe[i].communicate()[0] > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if = line and len(line) > 1: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 print "process %u pid %u: %s" % (i, pipe[i].pid, > line) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 sys.stdout.flush() > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if = pipe[i].poll() =3D=3D -1: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 waiting =3D True > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 els= e: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 return_value =3D pipe[i].poll() > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 if return_value !=3D 0: > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 print "Error: process =C2=A0%u pid %u retuned %u" = % > (i, pipe[i].pid, return_value) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 passed =3D False > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 print "process %u pid %u returned success" % (i, > pipe[i].pid) > =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 pipe[i] =3D None > =C2=A0 =C2=A0 =C2=A0 =C2=A0 sys.stdout.flush() > =C2=A0 =C2=A0 =C2=A0 =C2=A0 return passed > So what happens here is that in the waiting loop, if pipe[i].poll returns= a > -1, we keep waiting, and then if it returns anything OTHER than -1, we ex= it > and return the return code. Does self._command return a subprocess.Popen object? The documentation at http://docs.python.org/library/subprocess.html#subprocess.Popen.poll says that the poll method sets and returns the returncode attribute. returncode is expected to be None until the process terminates, and a negative value indicates that the subprocess has been terminated because of a signal. If poll() returns -1, it means that the process has been terminated by signal number 1 (probably SIGHUP). > BUT, I'm getting, in some cases, a return code of 127, which is impossibl= e > to get from the memory test program. > The output from this bit of code looks like this in a failing situation: > Error: process 0 pid 2187 retuned 127 > process 0 pid 2187 returned success > Error: process 1 pid 2188 retuned 127 > process 1 pid 2188 returned success > I'm thinking that I'm hitting some sort of race here where the kernel is > reporting -1 while the process is running, then returns 127 or some other > status when the process is being killed and then finally 0 or 1 after the > process has completely closed out. =C2=A0I "think" that the poll picks up= this > intermediate exit status and immediately exits the loop, instead of waiti= ng > for a 0 or 1. > I've got a modified version that I'm getting someone to test for me now t= hat > changes > =C2=A0if pipe[i].poll() =3D=3D -1: > =C2=A0 =C2=A0 =C2=A0waiting =3D True > to this > if pipe[i].poll() not in [0,1]: > =C2=A0 =C2=A0 waiting =3D True > So my real question is: am I on the right track here, and am I correct in= my > guess that the kernel is reporting different status codes to > subprocess.poll() during the shutdown of the polled process? > I'm unaware of any such race condition. It is more likely that the program you are running can return such error codes. Perhaps you should examine its stderr output. It's unclear what you're trying to do here. If you'd just like to wait until all the started processes are finished, you should use the wait() method instead of the poll() method. You should also note that the communicate() method already waits for the process to complete, so further calls to poll() and wait() are superfluous. Normally, after communicate() returns, you would simply check pipe[i].returncode and be on your way. --=20 regards, kushal