fredt has asked for the wisdom of the Perl Monks concerning the following question:

I have some long running batch-oriented CGI programs and I want to prevent multiple instances of the program from running at the same time. On unix, I'd hit this nail with the "flock" hammer, but I happen to be working on a windows server. I'm wondering: What's the "best" way to implement this mutual exclusion on windows, and, secondly, is "flock" safe and secure on windows? Many thanks.
  • Comment on mutual exclusion and file locking on windows

Replies are listed 'Best First'.
Re: mutual exclusion and file locking on windows
by tachyon (Chancellor) on Aug 07, 2001 at 18:56 UTC

    Perhaps the easiest way to prevent multiple instance of a CGI from running would be to write a semaphore file when the script first executes. The script checks if this semaphore exists and refuses to run if it does - instead it returns a "Busy, try later" message to the browser. Once the script has finished it deletes the sempahore file and exits opening the way for further instances of the script to have at it.

    use strict; use Fcntl qw(:DEFAULT); my $semaphore = 'c:/test.txt'; sysopen (SEMAPHORE, $semaphore, O_WRONLY | O_EXCL | O_CREAT) or &busy; print "There can be only one!"; sleep 20; close SEMAPHORE; unlink $semaphore or die "Can't unlink $semaphore $!\n"; exit; sub busy { print "Sorry, I am busy!"; exit; }

    The sysopen opens a file for writing (O_WRONLY); fails if the file already exists (O_EXCL) and creates a file if it does not exist (O_CREAT). It does this all in one step which help avoid race conditions. If this fails we do our busy sub. If it succeeds when the script finishes it unlinks the file so another instance of this script can run.

    While flock may work on some versions of Windows under 95/98 using Active State build 621 here is what happens:

    C:\>type flock.pl use Fcntl qw(:flock); print "This is $^O\n"; open FILE, ">>test.txt" or die "Oops $!\n"; flock FILE, LOCK_EX or die "Can't flock $!\n"; close FILE; C:\>perl flock.pl This is MSWin32 flock() unimplemented on this platform at flock.pl line 6. C:\>

    I am interested to know which versions of Win32 flock works under as it is clearly not all.

    cheers

    tachyon

    s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      It must be that flock works only on NT and Windows 2000. I tried your flock code and got the same failure on a Windows 98 machine, but it ran without error on a Windows 2000 server machine (ActiveState 626). Thanks for your help.

        No worries. I posted a question at Flock 'n Windows if you want to see all the systems that don't support flock. Using a semaphore is the workaround.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: mutual exclusion and file locking on windows
by c-era (Curate) on Aug 07, 2001 at 18:44 UTC
    flock works great on Windows, as long as all programs accessing the file also use flock. Activestate simulates flock on Windows. The only problem you will have with flock is if you access the file outside of perl, or don't call flock in one of your scripts (perl won't check to see if the file is locked unless you call flock at some point).

      Actually, under Windows (well, WinNT/Win2K), flock is mandatory unlike under Unix where it is advisory. This means that flock()ing a file prevents any other file handle (even from within the same process) from accessing the file. So you don't need the other programs to also use flock like you would under Unix. Not that this is really an improvement, just another difference to worry about (and a disadvantage in some cases).

              - tye (but my friends call me "Tye")
Re: mutual exclusion and file locking on windows
by $code or die (Deacon) on Aug 07, 2001 at 18:48 UTC
    ditto what c-era says.

    Also, you might want to check out Highlander for an example of this.

    TAWTCFE (There's a Web Techniques Column for everything) :p

    Error: Keyboard not attached. Press F1 to continue.