process and spinning slash

A

Alex Martelli

benz said:
def spin(delay):

pattern=['-','\\','|','/','-','\\','|']

while 1:
for i in pattern:
sys.stdout.write(i + " ")
sys.stdout.flush()
sys.stdout.write("\b\b")
time.sleep(delay)

pid = os.fork()

if pid == 0:
os.execvp("du",("du","-shc","/"))
else:
spin(0.05)


However, the spinner is kept spinning even the child process was ended.

It would be astonishing if it were otherwise! The loop in function spin
is deliberately coded to NEVER terminate, so of course it never does.
Any idea ? Thanks!

Have the spin function accept the pid argument and exit the loop if said
pid has terminated; to check the latter, e.g., os.kill(pid, 0) -- this
will raise an OSError if no process with that pid exists, so you can use
a try/except OSError: to catch that and break as appropriate.


Alex
 
A

Alex Martelli

Fredrik Lundh said:
or use the subprocess module instead of fork/exec, pass the Popen instance
to spin, and use the poll() method to check if the process is still running.

Much more elegant than the lower-level approach I was sketching, of
course, if one can use Python 2.4 (one cannot always sensibly do that;
e.g., Mac OS X Tiger [the latest release] includes Python 2.3.5, so if
you want to write Mac applications in Python 2.3 packaging and
distributing them is trivial, but if you want to use Python 2.4 you need
to distribute that as well, or package it with your app and thus make it
way bigger... so, limiting oneself to 2.3 is a reasonable choice here).


Alex
 
B

benz

I am trying to fork and exec a child by python. Additionally, I am
attempting
to have a spinning slash while the child is running.

My code is as below:

import sys, os, time


def spin(delay):

pattern=['-','\\','|','/','-','\\','|']

while 1:
for i in pattern:
sys.stdout.write(i + " ")
sys.stdout.flush()
sys.stdout.write("\b\b")
time.sleep(delay)

pid = os.fork()

if pid == 0:
os.execvp("du",("du","-shc","/"))
else:
spin(0.05)


However, the spinner is kept spinning even the child process was ended.
Any idea ? Thanks!
 
F

Fredrik Lundh

Alex said:
Have the spin function accept the pid argument and exit the loop if said
pid has terminated; to check the latter, e.g., os.kill(pid, 0) -- this
will raise an OSError if no process with that pid exists, so you can use
a try/except OSError: to catch that and break as appropriate.

or use the subprocess module instead of fork/exec, pass the Popen instance
to spin, and use the poll() method to check if the process is still running.

</F>
 
T

Thomas Bellman

Have the spin function accept the pid argument and exit the loop if said
pid has terminated; to check the latter, e.g., os.kill(pid, 0) -- this
will raise an OSError if no process with that pid exists, so you can use
a try/except OSError: to catch that and break as appropriate.

Bad idea.

Even after the process has exited, it will exist as a zombie until
you os.wait() och os.waitpid() for it. Sending signal 0 to it
will thus always succeed.

If you do wait for the child process, so the zombie disappears,
the process id can be reused by the OS. Some Unixes reuse pids
very quickly (if I remember correctly, AIX do so), and others more
slowly, but there is *always* the risk of the pid being reused
immediately after the zombie was removed. Of course, if you wait
for the process, you will know that it has died and don't need to
check by sending a signal to it if it is alive...

The best way to poll for the termination of a child process, is

dead_child, status = os.waitpid(pid, os.WNOHANG)
if dead_child == 0:
print "No child has died"
elif dead_child == pid:
print "The child process we waited for has died"
else:
print "Some other child process has died"

The last branch can't happen if you wait for a specific process.
(Process ids <= 0 given to waitpid have special meanings; read
the manual page for waitpid(2) for those.)

If the child process was started using subprocess.Popen, you
should usually use the poll() methods on the Popen object to
check if the process has terminated.
 
B

benz

I have rewrited my code as follow, but it still not working.

import os, sys


pid = os.fork()

if pid == 0:
os.execvp("du",("du","-shc","/usr/share"))
else:
while 1:
try:
os.kill(pid,0)
sys.stdout.write('running')
sys.stdout.flush()
sys.stdout.write('\b\b\b\b\b\b\b')
except OSError:
print "child ended"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top