JacquesB
JacquesB

Reputation: 42669

Starting a separate process

I want a script to start a new process, such that the new process continues running after the initial script exits. I expected that I could use multiprocessing.Process to start a new process, and set daemon=True so that the main script may exit while the created process continues running.

But it seems that the second process is silently terminated when the main script exits. Is this expected behavior, or am I doing something wrong?

Upvotes: 20

Views: 59705

Answers (6)

podcast
podcast

Reputation: 141

In Ubuntu the following commands keep working even though the python app exit.

url = "https://www.youtube.com/watch?v=t3kcqTE6x4A"  
cmd = f"mpv '{url}' && zenity --info --text 'you have watched {url}' &"
os.system(cmd)

Upvotes: 0

ilias iliadis
ilias iliadis

Reputation: 631

If you are on a unix system (using docs):

#!/usr/bin/env python3
import os
import sys
import time
import subprocess
import multiprocessing
from multiprocessing import Process

def to_use_in_separate_process(*args):
    print(args)

    #check args before using them:
    if len(args)>1:
        subprocess.call((args[0], args[1]))
        print('subprocess called')

def main(apathtofile):
    print('checking os')
    if os.name == 'posix':
        print('os is posix')
        multiprocessing.get_context('fork')
        p = Process(target=to_use_in_separate_process, args=('xdg-open', apathtofile))
        p.run()
    print('exiting def main')

if __name__ == '__main__':
    #parameter [1] must be some file that can be opened by xdg-open that this
    #program uses.
    if len(sys.argv)>1:
        main(sys.argv[1])
        print('we can exit now.')
    else:
        print('no parameters...')
    print('mother program will end now!')
    sys.exit(0)

Upvotes: 0

unutbu
unutbu

Reputation: 879611

If you are on a unix system, you could use os.fork:

import os
import time

pid=os.fork()
if pid:
    # parent
    while True:
        print("I'm the parent")
        time.sleep(0.5)    
else:
    # child
    while True:
        print("I'm just a child")
        time.sleep(0.5)

Running this creates two processes. You can kill the parent without killing the child. For example, when you run script you'll see something like:

% script.py
I'm the parent
I'm just a child
I'm the parent
I'm just a child
...

Stop the script with ctrl-Z:

^Z
[1]+  Stopped                 script.py

Find the process ID number for the parent. It will be the smaller of the two process ID numbers since the parent came first:

% ps axuw | grep script.py
unutbu    6826  0.1  0.1  33792  6388 pts/24   T    15:09   0:00 python /home/unutbu/pybin/script.py
unutbu    6827  0.0  0.1  33792  4352 pts/24   T    15:09   0:00 python /home/unutbu/pybin/script.py
unutbu    6832  0.0  0.0  17472   952 pts/24   S+   15:09   0:00 grep --color=auto script.py

Kill the parent process:

% kill 6826

Restore script.py to the foreground:

% fg
script.py
Terminated

You'll see the child process is still running:

% I'm just a child
I'm just a child
I'm just a child
...

Kill the child (in a new terminal) with

% kill 6827

Upvotes: 17

Philipp
Philipp

Reputation: 49812

Simply use the subprocess module:

import subprocess
subprocess.Popen(["sleep", "60"])

Upvotes: 13

Pontus
Pontus

Reputation: 1679

Here is a related question on SO, where one of the answers gives a nice solution to this problem:

"spawning process from python"

Upvotes: 1

Justin Ardini
Justin Ardini

Reputation: 9866

From the Python docs:

When a process exits, it attempts to terminate all of its daemonic child processes.

This is the expected behavior.

Upvotes: 16

Related Questions