2016-06-06 5 views
0

У меня цепь из трех процессов: процесс A вызывает B, чтобы порождать C, затем B умирает. Мы можем назвать B «мостом» между двумя системами A и C.Python; popen не проходит std *

Я хочу убедиться, что C не наследует никаких дескрипторов файлов, которые открывается A, чтобы предотвратить зомбинг, который я наблюдаю в настоящее время (иногда A вызывает B, чтобы убить C, и после этого, я вижу, что несуществующие процессы C висят вокруг, но я не знаю, как выглядит код в A).

Чтобы убедиться, что эта проблема не из-за стандартный ввод/из/ERR передаются вниз, настоящее время я делаю следующее B

def _close_fds(): #workaround carstens bug 
    for fd in [0, 1, 2]: 
     try: 
      os.close(fd) 
     except Exception: 
      logger.info("File descriptor was not open") 

... 
_close_fds() #make sure there are no open file descriptors for the chile to enherit 
pid = subprocess.Popen([_ROOT_PATH + "something.py"]).pid 
... 

Есть ли лучший способ сделать это?

+0

Вы только закрываете stdin, stdout и stderr. Если какие-либо другие дескрипторы файлов были открыты, они останутся открытыми, но вы их не найдете. – alexis

ответ

3

Когда вы начинаете процесс C с B, и вы не хотите, чтобы он наследовал любые файлы, используйте следующие аргументы в subprocess.Popen;

  1. close_fds=True
  2. Набор stdin, stdout и stderr к subprocess.PIPE или subprocess.DEVNULL.

Первый закрывает все дескрипторы файлов, за исключением стандартного ввода, стандартного вывода и STDERR. Аргументы, перечисленные в пункте (2), позаботятся об этом.

1

Модуль os обеспечивает хорошую функцию os.closerange(), которая будет делать это для вас в одном вызове:

os.closerange(0, 3) 

Если вы охотитесь после фантомных открытых файлов, я бы немного выше только в случае, если :

os.closerange(0, 10) 

чтобы узнать, что вы на самом деле нужно закрыть, вы можете проверить /proc/self/fd для списка дескрипторов файлов, что ваш процесс имеет открытый (если ваша операционная система поддерживает его), и/или использовать open_files() метод фр om psutil. См. Ответы на this question за еще больше идей.