Путать с идентификаторами процессов в Python 3 - PullRequest
0 голосов
/ 25 января 2019

У меня есть main.py, как показано ниже:

#!/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))

А 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()

Запуск main.py в терминале при следующем результате:

enter image description here

Почему идентификатор дочернего процесса, который мы получили от main.py, отличается от того, что мы получили от дочернего процесса внутри?

1 Ответ

0 голосов
/ 25 января 2019

Вы запускаете скрипт как /usr/bin/python3 ./runner.py, то есть как аргумент /usr/bin/python3, поэтому дерево PID становится:

  • main.py: Parent: PID = 16350
  • /usr/bin/python3: дочерний элемент (подпроцесс) main.py: PID = 16351
  • runner.py: внук до main.py, дочерний элемент до /usr/bin/python3: PID = 16352

Вы получите runner.py как потомок main.py, если вы выполните его напрямую (без запуска в качестве аргумента /usr/bin/python3):

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

Вам необходимо сделать runner.py исполняемым перед выполнениемэто прямо, очевидно.

В качестве отступления, попробуйте использовать обертку subprocess.run вместо прямого обмана вокруг subprocess.Popen (и братьев).

...