0

I am trying to develop a simple function that

  • opens a file,
  • starts a sub-process,
  • then closes the file,
  • then moves the file to a different location and
  • then stops the sub-process.

What happens is that I am unable to move the file as long as the sub-process is still executing even though I do not see how the two are connected. Because of this issue I moved the code portion to move the file into a thread that retries over and over and it finally succeeds only once the subprocess is terminated (I understand that termination can be done more gracefully but this is not the issue here that I am concerned of). What do I need to do differently to make the file accessible while the sub-process is still running so that I can avoid shifting this into a background process (I would much rather like to just call os.rename right there where I am instantiating the thread? Using 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)

The code when executed will produce the following output:

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 Answers1

0

The answer here is that the new thread started by subprocess inherits all open file handles from the main thread. This can be avoided by adding the 'N' flag to the prior open statement.

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

See Howto: workaround of close_fds=True and redirect stdout/stderr on windows for further details