How and why to lock data files with Perl

Two of the Perl questions we're often asked are:

  • "Why should I lock my data files when I'm writing to them?"
  • "How do I lock my data files with Perl?"

Here's a quick tutorial that demonstrates both the "why" and "how" of data file locking with Perl.

Why you should lock data files with Perl

The quick and simple answer to the why question is that any time you're writing a multi-user application and you're writing to a data file, you need to make sure that you're the only person writing to the data file at any given time. (Conversely, if it's not a multi-user or multi-threaded application, and you can be sure that only one program at any one time is writing to a data file, you won't need to lock your data files ... but you really need to be sure of this.)

Let's say you have two users named Sally and Fred, and they both try to write data to the same data file at the same time. If this happens, whose changes will be saved, and whose will be lost? Good question. The important thing is that if you don't control write access to that data file, you're opening yourself up to problems, and Sally or Fred won't be happy with you.

The "how" question

With Perl you lock access to data files using the flock function. The typical way to lock a data file with Perl is like this:

open (FILE, '>> test.dat');    # open the file
flock FILE, 2;                 # try to lock the file
                               # do something with the file here
flock FILE, 8;                 # unlock the file
close(FILE);                   # close the file

In this case, the number two in the first flock statement indicates that we want "exclusive" access to the file while we're trying to write to it. (More on this shortly.) In the second flock call, the number eight indicates that we want to unlock the file. Generally you'll replace the 2 and the 8 with a variable with a more meaningful name (see the examples below).

(Note: These values may be system-specific. Check your Unix man pages for the flock values on your system. We've used these values on a variety of systems without problems, but as they say, your mileage may vary.)

Sample programs

To help demonstrate how file-locking with Perl works, we've created two demo programs that you can try on your system.

The first program, 1lock.pl, opens the sample data file (test.dat), then goes to sleep for 10 seconds. After the 10-second nap it writes a line to the data file, then unlocks the file and exits.

The second program, 2try.pl, also opens the data file and attempts to put a lock on it. If everything works properly on your system, this program won't be able to write to the data file until the first program releases the lock. Once the lock is released, 2try.pl goes ahead and writes a different line to the data file.

If the test works properly, you can cat out the data file on a Unix/Linux system like this:

cat test.dat

The contents of the data file should look like this:

this is the first line of test.dat
this line printed by 1lock.pl
this line printed by 2try.pl

Download the demo files

If you're interested in running this test on your system, you can download the demo programs and data file from these links:

How to run the test

To run the test, you'll need two telnet/terminal windows open to your Unix system. Then you can follow these steps:

  1. Download the three files shown above.
  2. Put them in the same directory on your system.
  3. Make the two Perl programs executable (by running chmod +x *.pl)
  4. In your first terminal window, start the 1lock.pl program.
  5. Switch to the second terminal window, and run 2try.pl (you'll need to do this quickly, because the first program locks the file for only 10 seconds.)
  6. If everything works well, the first program will finish in 10 seconds, and the second program will finish immediately after that.
  7. Check the results by looking at the data file (cat test.dat). The file should contain the three lines shown earlier.

Hopefully this brief tutorial will help get you started down the road of locking data files in your Perl applications.