Python 2.7: вызов subprocess.popen блокирует доступ к файлу - PullRequest
0 голосов
/ 18 октября 2018

Я пытаюсь разработать простую функцию, которая

  • открывает файл,
  • запускает подпроцесс,
  • затем закрывает файл,
  • затем перемещает файл в другое место, а
  • затем останавливает подпроцесс.

Что происходит, так это то, что я не могу переместить файл, пока подпроцесс все еще выполняется, хотя я не вижу, как они связаны.Из-за этой проблемы я переместил часть кода, чтобы переместить файл в поток, который повторяется снова и снова, и это, наконец, завершается успешно только после завершения подпроцесса (я понимаю, что завершение может быть выполнено более изящно, но это не та проблема, которую яЯ обеспокоен).Что мне нужно сделать по-другому, чтобы сделать файл доступным, пока подпроцесс еще работает, чтобы я мог избежать смещения этого в фоновый процесс (я бы очень хотел просто вызвать os.rename прямо там, где я создаю экземплярпоток? Использование Python 2.7

import sys
import threading
import time
import random
import subprocess
import os

def GetFN():
    return 'C:\\temp\\' + str(random.randint(0,1000000)) + '.AVI'

class MoveFileThread(threading.Thread):
    def __init__(self, FromFilePath, ToFilePath):
        super(MoveFileThread, self).__init__()
        self.FromFilePath = FromFilePath
        self.ToFilePath = ToFilePath

    def run(self):
        while True:
            try:
                os.rename(self.FromFilePath, self.ToFilePath)
                print "Moved file to final location: " + self.ToFilePath
                break

            except Exception as err:
                print str(self.FromFilePath) + "'. Error: " + str(err)
                time.sleep(1)

if __name__ == "__main__":
    filename = GetFN()
    out = open(os.path.normpath(filename), "a")
    process = subprocess.Popen(['ping', '-t', '127.0.0.1'], stdout=subprocess.PIPE)
    time.sleep(2)
    out.close()
    MoveFileThread(filename, GetFN()).start()
    time.sleep(5)
    subprocess.Popen("TASKKILL /F /PID {pid} /T".format(pid=process.pid))
    time.sleep(3)

Код при выполнении даст следующий вывод:

C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
C:\temp\771251.AVI'. Error: [Error 32] The process cannot access the file because it is being used by another process
Moved file to final location: C:\temp\560980.AVI

1 Ответ

0 голосов
/ 18 октября 2018

Ответ заключается в том, что новый поток, запущенный подпроцессом, наследует все дескрипторы открытого файла из основного потока.Этого можно избежать, добавив флаг «N» к предыдущему открытому оператору.

out = open(os.path.normpath(filename), "a")

См. Howto: обходной путь close_fds = True и перенаправление stdout / stderr на окнах для получения дополнительной информации

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...