how to lock files

Posted on 2005-04-06
Last Modified: 2013-12-25
I have a working cgi  which read/writes config and status datas from a file, a write
attemp is done in lt 1 sec, I see problems if more then 1 user updates the file at the
same time , how can i avoid that more then 1 user has this file handle open  ?
Very cool would be to know who it is, like a user id, who requests the write operation.
i'm doing http auth. through apache and have the name already in my environ. .

Question by:MKrauss
    LVL 1

    Author Comment

    I forgot to stat that i'm using perl on a linux base ....
    LVL 51

    Expert Comment

    if your CGI is perl or C, then use flock(), but don't expect that it is 99% safe.
    Locking on modern filesystems is known to be a nightmare :-(

    The only reliable method, which works on mounted filesystems and with different hosts (think of a load balanced web server working on the same DocumentRoot), is to use another file as semaphore.
    This works like this (pseudo code):

      timestamp="`date +%s``uname -n`$$"
      echo $timestamp > /path/to/lock
      sleep 0.5sec
      read=`cat /path/to/lock`
      if ($read == $timestamp) {
        heureca, got the lock
        do my save action
        rm /path/to/lock
      } else {
       someone else kicked me out
    LVL 1

    Author Comment

    hmmm, somehow that looks a bit unfashion .... it's perl what i'm using,
    it's sure (or i assume) that all write request will be made from a single
    cgi script so athe load balanced issue does not affect me, is there a
    aternative way due to this facts ?
    Lets assume i go for timestamp/lock file solution, wouldnt it be possible
    to use the lock file owner somehow to see which user collide with the other ?
    I'm just thinking about a way to display who's conflicting with who ...
    Many thanks for helping ....
    LVL 18

    Accepted Solution

    Hi ahoffmann,
    > The only reliable method, which works

    how do you figure that?
    I routinely use flock over nfs (v3) mounts on heavily trafficked web sites, and have never had any problems.

    Here's what I use in perl:

        use 5.004;
        use Fcntl qw(:DEFAULT :flock);

        # for reading
            open(FH, "< $filename")  or die "can't open $filename: $!";
            unless (flock(FH, LOCK_SH | LOCK_NB)) {
                $| = 1;
                flock(FH, LOCK_SH)  or die "can't lock $filename: $!";
            local($/) = undef;
            $data = <FH>;
            close(FH) or die "can't close $filename: $!";

        # for writing
            sysopen(FH, "$filename", O_WRONLY | O_CREAT)
                or die "can't open $filename: $!";
            flock(FH, LOCK_EX)
                or die "can't lock $filename: $!";
            truncate(FH, 0)
                or die "can't truncate $filename: $!";
            # now write to FH
            print FH $data or die "can't write to $filename: $!";
            close FH or die "can't close $filename: $!";

    LVL 1

    Author Comment

    oh dear, i havent check your recommende flock option, think
    that will do it for me, i'll try and come back...
    But with flock i have no chance to figure out who it is or do i ?
    LVL 18

    Expert Comment

    > But with flock i have no chance to figure out who it is or do i ?

    why would you care? this code will make sure that each user gets his turn at writing to the file, so there are no conflicts.
    LVL 1

    Author Comment

    my only concern was to try to get who makes what, thats maybe oversized, but you're wright, this shouldnt conflict me,
    will try and come back ... thx
    LVL 51

    Expert Comment

    > I routinely use flock over nfs (v3) mounts on heavily trafficked web sites, and have never had any problems.
    you're lucky ;-)

    >  hmmm, somehow that looks a bit unfashion ..

    > ..  will be made from a single cgi script ..
    that's exactly your problem!
    if there is more than one request which starts this CGI, then you have at least 2 of them running, both trying to get the lock
    even the flock() function is an atomic one and hopefully not interuptable, you have to beat other dragons
    in particular disk caches

    You can be very safe if all happens on the same host and with a local filesystem. But if it is NFS, then  you run into problems more or less quickly .. believe me, or simply read
       perldoc -f flock
    LVL 18

    Expert Comment

    > you're lucky ;-)

    Maybe. But in my experience, nfs v3 comes with an excellent locking daemon, which works fine on multiple platforms, and across multiple mounts.
    I even used Microsoft's Interix nfs server in conjunction with several Debian web servers, and that did locking properly as well.
    LVL 51

    Assisted Solution

    kandura, it's not always NFS itself, just partialy, sometimes, somehow ...
    I know that Sun's NFS (wether local or remote) caches data to improve performance, and the SCSI driver caches again ... And Sun does this since SunOS early days :-(( they know that, wrote some "confidential" papers, and never fixed it, just giving the workaround to disable cahing at all which then makes NFS unusable for obvious reason.

    I won't complain or say that flock() *always* fails, but want to say that you should be aware of such problems. If someone asks for exclusive locks, (s)he  expects them working reliable, and that's not the case on NFS with flock(), neither perl's nor native libc's.
    LVL 1

    Author Comment

    Thanks for the interesting conversation,the  NFS issue does not affect me so i gues it's save
    to use flock.

    Featured Post

    Highfive Gives IT Their Time Back

    Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

    Join & Write a Comment

    In this tutorial I will focus on how to use WhizBase as a tool for sending ICQ messages to ICQ. Here I will use a new technology in WhizBase, published in WhizBase 5.1 version. In this tutorial I will use 3 files, pager.wbsp for the processing, e…
    This tutorial will discuss the log-in process using WhizBase. In this article I assume you already know HTML. I will write the code using WhizBase Server Pages, so you need to know some basics in WBSP (you might look at some of my other articles abo…
    Learn how to match and substitute tagged data using PHP regular expressions. Demonstrated on Windows 7, but also applies to other operating systems. Demonstrated technique applies to PHP (all versions) and Firefox, but very similar techniques will w…
    This tutorial will teach you the core code needed to finalize the addition of a watermark to your image. The viewer will use a small PHP class to learn and create a watermark.

    754 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    17 Experts available now in Live!

    Get 1:1 Help Now