Home > Software engineering >  Calling parent instance thru child in subprocess python
Calling parent instance thru child in subprocess python

Time:04-18

I have a file parent.py that calls its child called child.py using subprocess. Similar to this:

p = subprocess.Popen(["C:/Users/.../child.py", some_arg1, some_arg2],shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)

After the child process is started I would like to send a variable from the child process to the parent process. The child should not send a message when it is finished but at a certain point in its execution. How can I achieve this? After searching for several hours I only seem to find a solution the other way around (So from Parent to child). Thanks for your help.

CodePudding user response:

There are a few ways to facilitate this sort of inter-process communication. One of the more common ways is with a first-in-first-out (FIFO) named pipe.

Here's a very basic demo.

parent.py:

#! /usr/bin/env python3

import os, tempfile, subprocess

# make a temp directory that's automatically removed when we're done
with tempfile.TemporaryDirectory() as dir:

    # create a FIFO in that directory
    fifo_path = os.path.join(dir, 'fifo')
    os.mkfifo(fifo_path)

    # start the child process
    proc = subprocess.Popen(['./child.py', '--fifo', fifo_path])
    print('process started')

    # open the FIFO
    with open(fifo_path, 'r') as fifo:

        # read output from the child process
        mid_output = fifo.readline()
        print(f'{mid_output = }')

        # wait for child to finish
        code = proc.wait()
        print(f'process finished')

child.py:

#! /usr/bin/env python3

import argparse, time

# read FIFO path from command line
parser = argparse.ArgumentParser()
parser.add_argument('--fifo', required=True)
args = parser.parse_args()

# open FIFO (created by parent)
with open(args.fifo, 'w') as fifo:

    # simulate some work being done
    time.sleep(1)

    # tell the parent that progress has been made
    fifo.write('Halfway there!\n')
    fifo.flush()  # make sure to flush FIFOs

    # Simulate some more work being done
    time.sleep(1)

Then, it runs like so:

./parent.py
process started
mid_output = 'Halfway there!\n'
process finished

You can have the child script output whatever it needs to say to the parent, and you can have it do so multiple times. Just make sure that the parent knows to read from the child the same number of times that the child writes.

  • Related