tags:

views:

199

answers:

3

In Python under Windows: I want to run some code in a separate process. And I don't want the parent waiting for it to end. Tried this:

from multiprocessing import Process
from time import sleep

def count_sheeps(number):
    """Count all them sheeps."""
    for sheep in range(number):
        sleep(1)

if __name__ == "__main__":
    p = Process(target=count_sheeps, args=(5,))
    p.start()
    print("Let's just forget about it and quit here and now.")
    exit()

which starts the child process and continues executing. However, when the parent reaches the end, it still waits for the child to exit.

Is there a way of letting the parent quit even when the child is running? Sure, I could just run a new python interpreter using subprocess.Popen and feed to it the sheep-counting as a separate script.

Still, there's this whole module for playing with processes of Python code, so I'd like to take advantage of that instead of hacking on the OS. Also, it would be awesome if the same code worked everywhere where Python does, not just on Windows.

+2  A: 

Use the subprocess module as other subprocess control methods (os.system, os.spawn*, os.popen*, popen2., commands.) are being deprecated:

from subprocess import Popen
Popen( [ "foo.exe", "arg1", "arg2", "arg3" )

See the Python doco, especially P_NOWAIT example.

You will have to start a new Python interpreter in the subprocess, so "foo.exe" above will likely be "python.exe".

EDIT:

Having just reviewed the multiprocessing module documentation:

join_thread(): Join the background thread. This can only be used after close() has been called. It blocks until the background thread exits, ensuring that all data in the buffer has been flushed to the pipe.

By default if a process is not the creator of the queue then on exit it will attempt to join the queue’s background thread. The process can call cancel_join_thread() to make join_thread() do nothing.

cancel_join_thread(): Prevent join_thread() from blocking. In particular, this prevents the background thread from being joined automatically when the process exits – see join_thread().

It looks like you should be able to call cancel_join_thread() to get the behaviour you desire. I've never used this method (and was unaware of it's existence until a minute ago!), so be sure to let us know if it works for you.

Daniel Paull
Please don't `import *`.
Jed Smith
Sure - removed the import *
Daniel Paull
cancel_join_thread() seems to be for something else: so that process may exit even when a queue it uses is not empty.However, unless there is some queue silently created and filled in my example, I don't think this would help me here.
Tomas Sedovic
And thanks for the Popen examples. I already know and use the subprocess.Popen object. It's just that I hoped this could be done using the multiprocessing module instead.
Tomas Sedovic
+1  A: 

Under Linux you could fork but this won't work on Windows. I think the easiest way is to run a new Python process, by putting your count_sheeps in a seperate file and Popen('python count_sheeps.py')

THC4k
Agreed - the only difficulty is marshalling arguments to the method. Easy enough for count_sheeps( number ), where "number" is an integer. For complex arguments, the multiprocessing.Process method is a clever approach!
Daniel Paull
Yeah, it's pitty fork isn't on Windows. Seems like I will have to go this route.
Tomas Sedovic
A: 

You can always start a new thread, and call myNewThread.daemon(True) before invoking it's start() method.

That thread will continue to run when the main process exits.

Richo
Thanks, but not really. Daemon threads are killed when the main program exits.The differece from non-daemonic threads is that the program just kills them off instead of waiting for them to end on their own.
Tomas Sedovic