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

fork, exec, and disown

P: n/a
hello, i have a question about forking processes

atm, i have some code which i want to rewrite

os.system("cd ~ && exec " + cmd + " & disown")
i want to remove this os.system call
def fork_exec_disown(cmd, dir="~"):

if os.fork()==0:

os.chdir(os.path.expanduser(dir))
os.setsid()
os.umask(0)

if os.fork():
sys.exit(0)

cmd = cmd.split()
os.execvp(cmd[0], cmd)

but i am not sure that this have the same behaviour.

is the second fork needed ? i think so to detach the spawn process
i have found in the os doc, os.setsid, i think i have to use it.
am i going wrong or is this simple
def fork_exec_disown(cmd, dir="~"):

if os.fork()==0:
os.chdir(os.path.expanduser(dir))
cmd = cmd.split()
os.execvp(cmd[0], cmd)

a good replacement for my os.system call

thank you
Jul 18 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
>>>>> "Benoit" == Benoit Dejean <bn**@ifrance.com> writes:

Benoit> hello, i have a question about forking processes atm, i have
Benoit> some code which i want to rewrite

Benoit> os.system("cd ~ && exec " + cmd + " & disown")

Benoit> i want to remove this os.system call

Benoit> def fork_exec_disown(cmd, dir="~"):
Benoit> if os.fork()==0:
Benoit> os.chdir(os.path.expanduser(dir)) os.setsid() os.umask(0)
Benoit> if os.fork(): sys.exit(0)
Benoit> cmd = cmd.split() os.execvp(cmd[0], cmd)

Benoit> but i am not sure that this have the same behaviour. is the
Benoit> second fork needed ? i think so to detach the spawn process i
Benoit> have found in the os doc, os.setsid, i think i have to use it.

Benoit> am i going wrong or is this simple

Benoit> def fork_exec_disown(cmd, dir="~"):
Benoit> if os.fork()==0: os.chdir(os.path.expanduser(dir)) cmd =
Benoit> cmd.split() os.execvp(cmd[0], cmd)

Benoit> a good replacement for my os.system call

You can do that, but if you run ps you'll notice that all you processes get
into a Z (zombie), <defunct> state. Sooner or later you'll have the fork()
giving you error that "resource temporarily not available" because all
process numbers are used up. With the "double fork" technique you can avoid
this by adding a wait at the end:

def fork_exec_disown(cmd, dir="~"):
if os.fork() == 0:
if os.fork():
sys.exit(0)
os.chdir(os.path.expanduser(dir))
cmd = cmd.split()
os.execvp(cmd[0], cmd)
os.wait()

The wait will wait only for the child, not the grand-child. If you don't
have that you'll start accumulating zombies. In some OS you can avoid the
double forking overhead by manipulating the signal handler of SIGCHLD (so
that it has the flag SA_NOCLDWAIT and has handler SIG_IGN), but that is more
platform dependent than fork().

Regards,
Isaac.
Jul 18 '05 #2

P: n/a
Le Sun, 08 Feb 2004 22:22:37 +0800, Isaac To a écrit*:

You can do that, but if you run ps you'll notice that all you processes
get into a Z (zombie), <defunct> state. Sooner or later you'll have the
fork() giving you error that "resource temporarily not available"
because all process numbers are used up.
you're right, i haven't noticed that
With the "double fork" technique you can avoid this by adding a wait at
the end:

def fork_exec_disown(cmd, dir="~"):
if os.fork() == 0:
if os.fork():
sys.exit(0)
os.chdir(os.path.expanduser(dir))
cmd = cmd.split()
os.execvp(cmd[0], cmd)
os.wait()
ok, i use this
The wait will wait only for the child, not the grand-child. If you
don't have that you'll start accumulating zombies. In some OS you can
avoid the double forking overhead by manipulating the signal handler of
SIGCHLD (so that it has the flag SA_NOCLDWAIT and has handler SIG_IGN),
but that is more platform dependent than fork().


could you tell me more about that ?
because i am really interested in. i want to have the best/fastest
replacement for os.system

thank you
Jul 18 '05 #3

P: n/a
>>>>> "Benoit" == Benoit Dejean <bn**@ifrance.com> writes:

Benoit> Le Sun, 08 Feb 2004 22:22:37 +0800, Isaac To a écrit*:
You can do that, but if you run ps you'll notice that all you
processes get into a Z (zombie), <defunct> state. Sooner or later
you'll have the fork() giving you error that "resource temporarily
not available" because all process numbers are used up.
Benoit> you're right, i haven't noticed that
With the "double fork" technique you can avoid this by adding a wait
at the end:

def fork_exec_disown(cmd, dir="~"): if os.fork() == 0: if os.fork():
sys.exit(0) os.chdir(os.path.expanduser(dir)) cmd = cmd.split()
os.execvp(cmd[0], cmd) os.wait()
Benoit> ok, i use this
The wait will wait only for the child, not the grand-child. If you
don't have that you'll start accumulating zombies. In some OS you
can avoid the double forking overhead by manipulating the signal
handler of SIGCHLD (so that it has the flag SA_NOCLDWAIT and has
handler SIG_IGN), but that is more platform dependent than fork().


Benoit> could you tell me more about that ? because i am really
Benoit> interested in. i want to have the best/fastest replacement for
Benoit> os.system

E.g., in my Linux box, the following won't leave any zombie:

import os
import time
import signal
signal.signal(signal.SIGCHLD, signal.SIG_IGN)
def fork_exec_disown(cmd, dir="~"):
if os.fork() == 0:
os.chdir(os.path.expanduser(dir))
cmd = cmd.split()
os.execvp(cmd[0], cmd)
for i in xrange(1000):
fork_exec_disown("true")
time.sleep(100)

On the other hand, the effect is global, so once you do that you cannot
expect you can wait for process that have already been dead. E.g., the
following no longer work:
def f(): .... pid = os.fork()
.... if pid == 0:
.... os.execlp("true", "true")
.... time.sleep(1)
.... os.wait()
.... f()

Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "<stdin>", line 6, in f
OSError: [Errno 10] No child processes

So double forking has its merits, since it is per-child rather than
per-parent. And modern OS actually do fork() rather efficiently anyway.

Regards,
Isaac.
Jul 18 '05 #4

P: n/a
> So double forking has its merits, since it is per-child rather than
per-parent. And modern OS actually do fork() rather efficiently anyway.


thank you, i'll keep the double fork.

Jul 18 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.