Dong Nguyen
Dong Nguyen

Reputation: 1269

Confused with process IDs in Python 3

I have a main.py as below:

#!/usr/bin/env python3

import time
import os
import subprocess

fs = './runner.py'
child_process = subprocess.Popen(
    '/usr/bin/python3 ' + fs,
    shell=True
)


print('main process pid', os.getpid())
print('sub process pid', child_process.pid)
time.sleep(10)
os.system('kill ' + str(child_process.pid))

And runner.py:

#!/usr/bin/env python3

import os
import time

TIME_TO_CHECK_STATUS = 1


def init():
    pid = os.getpid()
    print('inside child process:')
    print(' --> pid: ', pid)
    def check():
        time.sleep(TIME_TO_CHECK_STATUS)
        check()
        return pid

    return check()


if __name__ == '__main__':
    init()

Running main.py in terminal given following result:

enter image description here

Why id of child process we got from main.py is different from what we got from child process inside?

Upvotes: 2

Views: 53

Answers (1)

heemayl
heemayl

Reputation: 42127

You are running the script as /usr/bin/python3 ./runner.py i.e. as an argument to /usr/bin/python3, so the PID tree becomes:

  • main.py: Parent: PID=16350
  • /usr/bin/python3: Child (Subprocess) of main.py: PID=16351
  • runner.py: Grandchild to main.py, child to /usr/bin/python3: PID=16352

You would get runner.py as child of main.py if you execute it directly (without running it as an argument to /usr/bin/python3):

child_process = subprocess.Popen('./runner.py', shell=True)

You need to make runner.py executable before executing it directly, obviously.

As an aside, try to use the subprocess.run wrapper instead of directly mucking around subprocess.Popen (and brothers).

Upvotes: 2

Related Questions