2016-08-02 3 views
2

У меня есть сценарий test1.py (к примеру)Python дважды открывает файл, если используется subprocess.Popen для запуска другого сценария

import test2 


def main(): 
    f = open("File.txt") 
    test2.run() 

    while True: 
     pass 

if __name__ == '__main__': 
    main() 

И test2.py

import subprocess, sys, os 

def run(): 
    # Self run 
    subprocess.Popen(['C:\\Windows\\System32\\cmd.exe', '/C', 'start', 
          sys.executable, os.path.abspath(__file__)]) 

def main(): 
    while True: 
     pass 

if __name__ == '__main__': 
    main() 

Проблема заключается в том, что запуск второго скрипта снова откроет файл «File.txt». Почему второй скрипт при запуске открывает файл?

D:\test>Handle.exe File.txt 

Handle v4.0 
Copyright (C) 1997-2014 Mark Russinovich 
Sysinternals - www.sysinternals.com 

python.exe   pid: 9376 type: File   29C: D:\test\File.txt 
python.exe   pid: 9792 type: File   29C: D:\test\File.txt 

ответ

1

дочерний процесс наследует дескриптор файла для совместимости с моделью Unix (см PEP 446 для более подробного объяснения). После вызова подпроцесса как исходный, так и новый скрипт должны иметь доступ к файлу; в Windows, что означает открытие двух отдельных дескрипторов файлов.

Лучше идиома, если вы хотите, чтобы избежать этого, необходимо закрыть файл перед разветвлением, либо явно, либо используя with конструкцию:

with open('File.txt', 'r') as inputfile: 
    pass # or do something with inputfile 
+0

Я привел простой пример, для инструкций моих проблем. Мой код немного сложнее, поэтому я не могу закрыть файл перед форкингом. Можно ли подавить дочерний процесс наследовать файловый дескриптор? – deniska369

+0

Подпроцесс может закрыть его, если вы ожидаете, что он будет длительным процессом, и если несколько обработок файлов вызывают дополнительную проблему. – Owen

+1

Хорошо, я нашел решение. Нужно установить close_fds = True в подпроцессе.Popen. Большое спасибо за ваш ответ – deniska369

1

К тому времени вы называете test2 программа test1 уже открыт файл , Поэтому при создании подпроцесса дочерний процесс наследует любые открытые файлы, включая File.txt.

См. notes on file inheritance в документации по subprocess.

+0

Могу ли я запретить дочернему процессу наследовать этот открытый файл? – deniska369

+0

Хорошо, я нашел решение. Нужно установить close_fds = True в подпроцессе.Popen. Большое спасибо за ваш ответ – deniska369

Смежные вопросы