fork, exec, and disown

B

Benoit Dejean

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
 
I

Isaac To

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.
 
B

Benoit Dejean

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
 
I

Isaac To

Benoit> Le Sun, 08 Feb 2004 22:22:37 +0800, Isaac To a écrit :
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

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)

.... pid = os.fork()
.... if pid == 0:
.... os.execlp("true", "true")
.... time.sleep(1)
.... os.wait()
.... 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.
 
B

Benoit Dejean

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.
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top