我正在尝试开发一个简单的功能
发生的事情是,即使子进程仍在执行,我也无法移动文件,即使我看不到两者如何连接。由于这个问题,我移动了代码部分,将文件移入一个线程,该线程一遍又一遍地重试,只有在子进程终止后,它才最终成功(我知道终止可以更优雅地完成,但这不是我要解决的问题关注)。我需要做些什么来使子进程仍在运行时可访问该文件,以便避免将其转移到后台进程(我更想在实例化该位置的那儿直接调用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
答案 0 :(得分:0)
这里的答案是,由子进程启动的新线程将从主线程继承所有打开的文件句柄。可以通过在先前的open语句中添加'N'标志来避免这种情况。
out = open(os.path.normpath(filename), "a")
有关更多详细信息,请参见Howto: workaround of close_fds=True and redirect stdout/stderr on windows