views:

123

answers:

2

The relevant part of the code looks like this:

pids = [] 
for size in SIZES:
    pids.append(os.spawnv(os.P_NOWAIT, RESIZECMD, [RESIZECMD, lotsOfOptions]))

# Wait for all spawned imagemagick processes to finish
while pids:
    (pid, status) = os.waitpid(0, 0)
    if pid:
        pids.remove(pid)

What this should be doing is spawning all of the processes off, then waiting for each process to finish before continuing. What it does is work for the most part but sometimes crash on the next section (when it expects all of these processes to be finished).

Is there something wrong with this? Is there a better way of doing it?

The environment it has to work on is CentOS with Python 2.4, but I'm testing on Cygwin with Python 2.5, so it could be that it fails on my machine but will work on the Linux one (the Linux machine is very slow and this error is rare, so I haven't been able to get it on there).

+2  A: 

I would recommend you install python-subprocess32 -- a robust backport of Python 3's version of the subprocess standard library module, suitable for Python 2.4 to 2.7, and by far the best way to run subprocesses in Python 2. Then, in the loop you'll do

pids.append(subprocess.Popen([RESIZECMD, lot, of, options])

and the following loop will just be a simple

for pid in pids:
    pid.wait()
Alex Martelli
I'm confused about why I would need to install that module when `subprocess.Popen()` works fine in Python 2.4
Brendan Long
@Brendan, crucial bug fixes, esp. for programs that use both subprocess and threads -- that's mentioned on the short page I pointed you to, it's the whole 2nd paragraph. Is there any reason why you need the complete list of fixes...? EINTR handling, no more problems with large FDs, no more FD/handle leaks...
Alex Martelli
Oh I see. I asked because this is a work project and it's much easier if I don't have to install anything new. Thanks.
Brendan Long
@Brendan, you don't _have_ to install the fixed version (just like you don't have to install any given bug fix from software suppliers); if you have no threads, not a long-running parent process so the leaks and large FDs are no issue, and no interrupts sent to the parent process, etc etc, the bugs won't show up (that's how they survived so long... they're intermittent, hard to reproduce, and only occur in such specific classes of use cases!-).
Alex Martelli
+1  A: 

The recommended way to start subprocess is to use the subprocess module.

pipe = Popen(["program", "arg1", "arg2"])
pipe.wait()
lazy1