Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Fire and forget" a process from a Python script

How do I start a process (another Python script, for example) from a Python script so the "child" process is completely detached from the "parent", so the parent can a) continue on its merry way without waiting for child to finish and b) can be terminated without terminating the child process?

Parent:

import os

print "Parent started"
os.system("./child.py")
print "Parent finished"

Child:

import time

print "Child started"
time.sleep(10)
print "Child finished"

Running parent.py prints:

Parent started
Child started
Child finished
Parent finished

What I want it to print:

Parent started
Child started
Parent finished
(seconds later)
Child finished
like image 718
Sergey Avatar asked Jul 30 '13 02:07

Sergey


People also ask

How do you stop a process running in Python?

To stop a script in Python, press Ctrl + C. If you are using Mac, press Ctrl + C. If you want to pause the process and put it in the background, press Ctrl + Z (at least on Linux). Then, if you want to kill it, run kill %n where “n” is the number you got next to “Stopped” when you pressed Ctrl + Z.

How do you terminate a file in Python?

remove() method in Python can be used to remove files, and the os. rmdir() method can be used to delete an empty folder. The shutil. rmtree() method can be used to delete a folder along with all of its files.


1 Answers

Since you mentioned os.system, I think it's worth to mention that you should have used os.spawn* with mode P_NOWAIT to achieve the "forget" part.

But subprocess module provides replacements for os.system, os,spawn*,etc so you should use that instead like so

import subprocess
p = subprocess.Popen("./child.py")
print "pid = ", p.pid

See Replacing os.spawn with subprocess.Popen

As I explained in the comments both processes parent.py and child.py are still on the same process group and therefore the terminal will forward signals (like Ctrl-C) to all process in the foreground process group so both will get killed when you Ctrl-C. So if you don't want that you can force child.py to be in a new process group with the following:

#!/usr/bin/env python
import subprocess
import time
import os
p = subprocess.Popen("./child.py", preexec_fn=os.setsid)
print "pid = ", p.pid
time.sleep(30) # Ctrl-C at this point will not kill child.py
print "parent exit"
like image 173
RubenLaguna Avatar answered Sep 23 '22 09:09

RubenLaguna