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

Posted

技术标签:

【中文标题】Python 2.7:调用 subprocess.popen 阻止文件访问【英文标题】:Python 2.7: Call to subprocess.popen blocks file access 【发布时间】:2019-03-22 16:05:21 【问题描述】:

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

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

发生的情况是,只要子进程仍在执行,即使我看不到两者是如何连接的,我也无法移动文件。由于这个问题,我移动了代码部分以将文件移动到一个反复重试的线程中,并且只有在子进程终止后它才最终成功(我知道终止可以更优雅地完成,但这不是我的问题我担心)。我需要做些什么来使文件在子进程仍在运行时可以访问,这样我就可以避免将其转移到后台进程中(我更愿意在我正在实例化的地方调用 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】:

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

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

详情请见Howto: workaround of close_fds=True and redirect stdout/stderr on windows

【讨论】:

以上是关于Python 2.7:调用 subprocess.popen 阻止文件访问的主要内容,如果未能解决你的问题,请参考以下文章

python常用内置模块

Python学习之路 - Subprocess 模块

Python调用linux系统命令--使用subprocess模块

Python 调用外部命令:subprocess 模块

socket实现在python中调用操作系统的命令(subprocess)

python使用subprocess及delegator调用第三方程序