2

I have a computer that is running Windows XP that I am using to process a great deal of data, update monitors, and bank data. Generally it is pretty loaded with work.

One particular file that has real time data is useful to a number of users. We have two programs that need this file, one that displays the numerical data and one that plots the numerical data. Any user can run an instance of either program on their machine. These programs search for the real time data file which is updated every second. They are both written in Perl and I was asked not to change either program.

Because of the large load on the computer, I am currently running the program that does calculations and creates the real time data file on a separate computer. This program simply writes the real time file onto the overloaded computer. Because Windows doesn't have an atomic write, I created a method that writes to a different extension, deletes the old real time file, and then moves the new one to the correct name. Unfortunately, as the user load on the computer increases, the writes take longer (which isn't ideal but is live-able) but more annoyingly, the time between deleting the old real time file and moving the new file to the correct name increases a great deal, causing errors with the Perl programs. Both programs check to see if the file modify time has changed (neither check for file locks). If the file goes missing they get angry and output error messages.

I imagine a first course of action would be to move this whole process away from the overloaded computer. My other thought was to create a number of copies of the files on different machines and have different users read the file from different places (this would be a real hack though).

I am new to the world networking and file sharing but I know there is a better way to do this. Frankly this whole method is a little hacked but that's how it was when I came here.

Lastly, it's worth mentioning that this same process runs on a UNIX machine and has none of these problems. For this reason I feel the blame falls on a need for an atomic write. I have been searching the internet for any work around to this problem and have tried a number of different methods (eg my current extension switching method).

Can anyone point me in the right direction so I can solve this problem?

My code is written in Python.

Paul Seeb
  • 6,006
  • 3
  • 26
  • 38

1 Answers1

3

os.rename() says:

os.rename(src, dst)
    Rename the file or directory src to dst. If dst is a directory,
    OSError will be raised. On Unix, if dst exists and is a file,
    it will be replaced silently if the user has permission. The
    operation may fail on some Unix flavors if src and dst are on
    different filesystems. If successful, the renaming will be an
    atomic operation (this is a POSIX requirement). On Windows, if
    dst already exists, OSError will be raised even if it is a file;
    there may be no way to implement an atomic rename when dst names
    an existing file.

Given that on Windows you are forced to delete the old file before renaming the new one to it, and you are prohibited from modifying the reading scripts to tolerate the missing file for a configurable timeout (the correct solution) or do proper resource locking with the producer (another correct solution), your only workaround may be to play with the process scheduler to make the {delete, rename} operation appear atomic. Write a C program that does nothing but look for the new file, delete the old, and rename the new. Run that "pseudo-atomic rename" process at high priority and pray that it doesn't get task-switched between the delete and the rename.

Dave
  • 3,834
  • 2
  • 29
  • 44
  • I don't really know much about setting processes to high priority. Is there any way to do this for a function call in python? I feel like if I am just running another language from my python code I might as well use something like my cygwin mv command which already replaces files silently (maybe implementing a method similar to what you are saying?) – Paul Seeb Nov 08 '11 at 15:15
  • Sure, that would work just as well. Setting the scheduler priority isn't necessary, it was just a suggestion to make the operation as reliable as possible under any CPU load. – Dave Nov 08 '11 at 16:29
  • See also http://stackoverflow.com/questions/167414/is-an-atomic-file-rename-with-overwrite-possible-on-windows. – Dave Nov 08 '11 at 16:47
  • I had read that link previously. I agree with your edit about the "correct solutions". I also see that decreasing the load despite the number of users will allow that file to update more regularly and avoid the task switching between the remove and rename commands. Would it make a serious difference if I had these operations run on the CPU rather than compete for a communication port? (aka does the fact that I am competing with many other users who are trying to read the file play a significant role in time between my remove and rename? I think this is the behavior I am seeing. – Paul Seeb Nov 08 '11 at 20:10