C.Qian
C.Qian

Reputation: 169

AssertionError: can only start a process object created by current process

Currently I have 3 Process A,B,C created under main process. However, I would like to start B and C in Process A. Is that possible?

process.py

from multiprocessing import Process

procs = {}
import time

def test():
    print(procs)
    procs['B'].start()
    procs['C'].start()
    time.sleep(8)

    procs['B'].terminate()
    procs['C'].termiante()

    procs['B'].join()
    procs['C'].join()




def B():
    while True:
        print('+'*10)
        time.sleep(1)
def C():
    while True:
        print('-'*10)
        time.sleep(1)


procs['A'] = Process(target = test)
procs['B'] = Process(target = B)
procs['C'] = Process(target = C)

main.py

from process import *
print(procs)
procs['A'].start()
procs['A'].join()

And I got error AssertionError: can only start a process object created by current process

Are there any alternative way to start process B and C in A? Or let A send signal to ask master process start B and C

Upvotes: 4

Views: 2072

Answers (1)

Thomas Moreau
Thomas Moreau

Reputation: 4467

I would recommend using Event objects to do the synchronization. They permit to trigger some actions across the processes. For instance

from multiprocessing import Process, Event
import time

procs = {}


def test():
    print(procs)

    # Will let the main process know that it needs
    # to start the subprocesses
    procs['B'][1].set()
    procs['C'][1].set()
    time.sleep(3)

    # This will trigger the shutdown of the subprocess
    # This is cleaner than using terminate as it allows
    # you to clean up the processes if needed.
    procs['B'][1].set()
    procs['C'][1].set()


def B():
    # Event will be set once again when this process
    # needs to finish
    event = procs["B"][1]
    event.clear()
    while not event.is_set():
        print('+' * 10)
        time.sleep(1)


def C():
    # Event will be set once again when this process
    # needs to finish
    event = procs["C"][1]
    event.clear()
    while not event.is_set():
        print('-' * 10)
        time.sleep(1)


if __name__ == '__main__':
    procs['A'] = (Process(target=test), None)
    procs['B'] = (Process(target=B), Event())
    procs['C'] = (Process(target=C), Event())
    procs['A'][0].start()

    # Wait for events to be set before starting the subprocess
    procs['B'][1].wait()
    procs['B'][0].start()
    procs['C'][1].wait()
    procs['C'][0].start()

    # Join all the subprocess in the process that created them.
    procs['A'][0].join()
    procs['B'][0].join()
    procs['C'][0].join()

note that this code is not really clean. Only one event is needed in this case. But you should get the main idea.

Also, the process A is not needed anymore, you could consider using callbacks instead. See for instance the concurrent.futures module if you want to chain some async actions.

Upvotes: 3

Related Questions