简体   繁体   中英

How to make sure the child process does not terminate when the parent does?

I have a parent process that runs a child process in a class. The child process takes much longer to complete. I want to make sure that the child process is not going to terminate when the parent process is terminated. How do I do that?

Here's a very simplified version of my code:

# myClass.py
from multiprocess import Process
class myClass(self):
    def __init__(self):
        print ('setup the object')
    def parentProcess(self, idx)
        p = Process(target=childFunc)
        p.start()
        time.sleep(3)
        print ('parent is done with ' + str(idx))
    def childProcess(self):
        print ('do some childish stuff')
        time.sleep(8)

And this is how I run the parent process

# main.py
from multiprocessing import Process
myClass import myClass
myC = myClass()
for i in range(10):
    p = Process(target=myC.parentProcess, args=i)
    p.start()
    p.join()

Your program will not terminate until all the processes are done. Try this:

from multiprocessing import Process

import time


def foo():
    time.sleep(2)
    print("Now I am done")


if __name__ == "__main__":
    p = Process(target=foo)
    p.start()
    print("I am done.")

However, to control the execution of your processes:

  • Use child.join() to wait for the child process to end.

  • You should use two loops, one for starting the processes and one for joining them

Try this:

from multiprocessing import Process

import time


class MyClass():
    def __init__(self, idx):
        self.idx = idx

    def start_parent(self):
        p = Process(target=self.child_func)
        p.start()
        time.sleep(1)
        print('parent is done, waiting for child', self.idx)
        p.join()
        print('parent exiting', self.idx)

    def child_func(self):
        print('child start', self.idx)
        time.sleep(2)
        print('child end', self.idx)

if __name__ == "__main__":
    parents = []
    for i in range(10):
        o = MyClass(i)
        p = Process(target=o.start_parent)
        parents.append(p)
        p.start()

    for p in parents:
        p.join()

    print("all done")

Or even better, subclass Process and implement run() :

from multiprocessing import Process

import time


class ParentProcess(Process):
    def __init__(self, idx, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.idx = idx

    def run(self):
        print('parent start', self.idx)
        child = ChildProcess(self)
        child.start()
        time.sleep(1)
        print('waiting for child', self.idx)
        child.join()
        print('parent end', self.idx)


class ChildProcess(Process):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.parent = parent

    def run(self):
        print('child start', self.parent.idx)
        time.sleep(5)
        print('child end', self.parent.idx)


if __name__ == "__main__":
    parents = [ParentProcess(i) for i in range(10)]
    for p in parents:
        p.start()

    for p in parents:
        p.join()

    print("all done")

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM