Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Re: possible bug?

5 views
Skip to first unread message

Earl Eiland

unread,
Mar 22, 2005, 2:15:33 PM3/22/05
to Jeff Epler, pytho...@python.org
I'm running the following code on Windows 2000, 5.00.2195:

for x in Files:
Command_String = 'C:\Program Files\WinRK\WinRK.exe -create ' +
os.path.join(InputDirectory, os.path.splitext(x)[0]) + ' -set
compression_method ppmz -setg include_paths none -add ' +
os.path.join(InputDirectory, x) + ' -apply -quit'
PROC = subprocess.Popen(Command_String)
PROC.wait()
... # process WinRK output

This hangs occasionally, and is not repeatable - it never hangs on the
same file.

Replacing the PROC.wait() command with the loop

while PROC.poll() == None: time.sleep(1)

has not hung on approximately 7,000 calls to WinRK.

Earl

On Tue, 2005-03-22 at 09:35, Jeff Epler wrote:
> On Tue, Mar 22, 2005 at 07:16:11AM -0700, Earl Eiland wrote:
> > I've been having trouble with a program hanging when using the
> > subprocess modules "wait()" method. Replacing it with with a loop that
> > used "poll()" solved the problem.
>
> Please include an example, and more information about what platforn you're using
> This simple program worked fine for me on Linux with Python 2.4:
> #------------------------------------------------------------------------
> import subprocess, time
>
> s = subprocess.Popen(['sleep', '2'])
> while 1:
> time.sleep(.1)
> if s.poll() is not None: break
> print "polling wait done", s.returncode
>
> s = subprocess.Popen(['sleep', '2'])
> s.wait()
> print "blocking wait done", s.returncode
> #------------------------------------------------------------------------
>
> Jeff

Earl Eiland

unread,
Mar 22, 2005, 3:11:24 PM3/22/05
to Jeff Epler, pytho...@python.org
I'm running ActivePython PythonWin 2.4, and get the error
message"'AributeError: 'module' object has no attribute 'SIGALRM'". The
example provided in the ActivePython documents use signal.SIGALRM, so
I'm not sure what's going on...

Earl


On Tue, 2005-03-22 at 12:43, Jeff Epler wrote:
> I wrote a program to use subprocess.Popen 10000 times, and never had
> .wait() hang. If this is a bug, it may be Windows specific.
>
> Here's the program I ran:
> #-------------------------------------------------------------------------
> import subprocess, signal
> def timeout(*args):
> print "Timed out waiting on", i
> raise SystemExit, 1
>
> signal.signal(signal.SIGALRM, timeout)
>
> for i in xrange(10000):
> signal.alarm(5)
> subprocess.Popen(['/bin/true']).wait()
> if i % 100 == 0: print "done with", i
> print "done!"
> #-------------------------------------------------------------------------
>
> If the wait method ever hangs, the signal handler shuld be invoked. On
> Unix, "/bin/true" is a very simple program that does nothing, so it's
> virtually guaranteed to run in less than 5 seconds. On Windows, maybe
> you want something like subprocess.popen('cmd.exe /c rem') as a command
> that will do nothing and terminate quickly. What happens if you run my
> program with that change to the Popen line?
>
> Jeff

Jeff Epler

unread,
Mar 22, 2005, 11:35:17 AM3/22/05
to Earl Eiland, pytho...@python.org

Earl Eiland

unread,
Mar 22, 2005, 9:16:11 AM3/22/05
to pytho...@python.org
I've been having trouble with a program hanging when using the
subprocess modules "wait()" method. Replacing it with with a loop that
used "poll()" solved the problem.

Earl

Earl Eiland

unread,
Mar 22, 2005, 4:19:52 PM3/22/05
to Jeff Epler, pytho...@python.org
Well, your program ran successfully. Perhaps WinRK is not well
behaved. How can a process terminate in such a way that poll() can read
it, but wait() won't?

Earl

On Tue, 2005-03-22 at 13:49, Jeff Epler wrote:
> hm, I guess SIGALRM doesn't exist on Windows. You can run the program
> without the 'signal.signal' line or the 'signal.alarm' line, and you'll
> be stuck with a hung Python if subprocess.Popen exhibits the bug.
>
> Jeff

Jeff Epler

unread,
Mar 22, 2005, 4:31:01 PM3/22/05
to Earl Eiland, pytho...@python.org
On Tue, Mar 22, 2005 at 02:19:52PM -0700, Earl Eiland wrote:
> Well, your program ran successfully. Perhaps WinRK is not well
> behaved. How can a process terminate in such a way that poll() can read
> it, but wait() won't?

I don't have any idea. Both are implemented in terms of
win32event.WaitForSingleObject (which is itself a thin wrapper over the
win32 API of the same name[1]), one with a zero timeout and one with an
INFINITE timeout.

This caveat is in the msdn page on WFSO:
Use caution when calling the wait functions and code that directly
or indirectly creates windows. If a thread creates any windows, it
must process messages. Message broadcasts are sent to all windows in
the system. A thread that uses a wait function with no time-out
interval may cause the system to become deadlocked. Two examples of
code that indirectly creates windows are DDE and the CoInitialize
function. Therefore, if you have a thread that creates windows, use
MsgWaitForMultipleObjects or MsgWaitForMultipleObjectsEx, rather
than WaitForSingleObject.
... which is pretty much greek to this unix geek. If your Python
program has a GUI, can you strip out the gui-related parts to make it a
pure commandline program, and see if you still have the problem?

You could try something like (untested, obviously)
import subprocess
if subprocess.mswindows:
from win32event import WaitForSingleObject
from win32process import GetExitCodeProcess
def wait(self):
"""Wait for child process to terminate. Returns returncode
attribute."""
while self.returncode is None:
obj = WaitForSingleObject(self._handle, 1000)
self.returncode = GetExitCodeProcess(self._handle)
_active.remove(self)
return self.returncode
subprocess.Popen.wait = wait
to make the .wait() method call WFSO with a timeout, and then maybe you
can simply forget about the weird behavior you ran into.

Jeff
[1] http://msdn.microsoft.com/library/en-us/dllproc/base/waitforsingleobject.asp

Jeff Epler

unread,
Mar 22, 2005, 3:49:05 PM3/22/05
to Earl Eiland, pytho...@python.org

Jeff Epler

unread,
Mar 22, 2005, 2:43:22 PM3/22/05
to Earl Eiland, pytho...@python.org

Tim Roberts

unread,
Mar 24, 2005, 2:16:59 AM3/24/05
to
Earl Eiland <e...@nmt.edu> wrote:

>I'm running the following code on Windows 2000, 5.00.2195:
>
>for x in Files:
> Command_String = 'C:\Program Files\WinRK\WinRK.exe -create ' +

That can't be right. You need either


Command_String = 'C:\\Program Files\\WinRK\\WinRK.exe -create ' +

or
Command_String = r'C:\Program Files\WinRK\WinRK.exe -create ' +
--
- Tim Roberts, ti...@probo.com
Providenza & Boekelheide, Inc.

Earl Eiland

unread,
Mar 24, 2005, 11:30:09 AM3/24/05
to Tim Roberts, pytho...@python.org
There may be different ways to code it. This works. The problem is
that occasionally somehow, WinRK terminates without terminating the
process, or at least Python doesn't pick up the return code. It turns
out that using poll() instead of wait() only reduces the error
frequency, and allows me to recover from the failure. It doesn't
eliminate it.

Earl

Peter Hansen

unread,
Mar 24, 2005, 12:22:48 PM3/24/05
to
Earl Eiland wrote:
> There may be different ways to code it. This works.

You're right about that, *as the code now stands*.

The danger is that you are using single backslashes.
The *only* reason this works right now is because none
of the characters you have following those backslashes
happen to be part of reserved escape sequences. See
http://docs.python.org/ref/strings.html to learn why
Tim is basically right, even though in this case you
are getting away with it...

(Yes, I know this doesn't solve the real problem.)

-Peter

0 new messages