Python 2.7:对subprocess.popen的调用会阻止文件访问

时间:2018-10-17 21:37:01

标签: python-2.7 subprocess filelock

我正在尝试开发一个简单的功能

  • 打开文件,
  • 启动一个子流程,
  • 然后关闭文件,
  • 然后将文件移动到其他位置,然后
  • 然后停止子流程。

发生的事情是,即使子进程仍在执行,我也无法移动文件,即使我看不到两者如何连接。由于这个问题,我移动了代码部分,将文件移入一个线程,该线程一遍又一遍地重试,只有在子进程终止后,它才最终成功(我知道终止可以更优雅地完成,但这不是我要解决的问题关注)。我需要做些什么来使子进程仍在运行时可访问该文件,以便避免将其转移到后台进程(我更想在实例化该位置的那儿直接调用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 :(得分:0)

这里的答案是,由子进程启动的新线程将从主线程继承所有打开的文件句柄。可以通过在先前的open语句中添加'N'标志来避免这种情况。

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

有关更多详细信息,请参见Howto: workaround of close_fds=True and redirect stdout/stderr on windows