By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
439,957 Members | 2,017 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 439,957 IT Pros & Developers. It's quick & easy.

process and spinning slash

P: n/a
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!

Oct 30 '05 #1
Share this Question
Share on Google+
6 Replies


P: n/a
benz <be****@yahoo.com.tw> wrote:
...
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
Oct 30 '05 #2

P: n/a
Alex Martelli wrote:
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>

Oct 30 '05 #3

P: n/a
Fredrik Lundh <fr*****@pythonware.com> wrote:
Alex Martelli wrote:
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.


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
Oct 30 '05 #4

P: n/a
al*****@yahoo.com (Alex Martelli) writes:
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.
--
Thomas Bellman, Lysator Computer Club, Linköping University, Sweden
"You are in a twisty little passage of ! bellman @ lysator.liu.se
standards, all conflicting." ! Make Love -- Nicht Wahr!
Oct 30 '05 #5

P: n/a
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"

Oct 31 '05 #6

P: n/a
"benz" <be****@yahoo.com.tw> wrote
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"


thomas has already explained why that doesn't work:

http://article.gmane.org/gmane.comp....general/428821

</F>

Oct 31 '05 #7

This discussion thread is closed

Replies have been disabled for this discussion.