[Canberra-pm] How to flock a file for to ensure only one CGI BIN script process at a time

John.Hockaday@ga.gov.au John.Hockaday at ga.gov.au
Thu Aug 11 19:15:14 PDT 2005


Hi Paul,

Firstly thanks for the reply to my email.  Secondly I apologise for not
replying earlier but I have been sick.

The information that you sent me was very useful.  I didn't want the script
to stop working when someone was using it.  I just wanted the script to
report to the web page that a very CPU expensive sub routine of the script
was running and to try again later. 

Here is part of the code that works well for me.  You probably all know this
but I thought that I had better show you my solution just in case someone
else had the same problem.  I have left out the nitty gritty processing and
html printing sub-routines:

#!/usr/local/bin/perl
use CGI;
use strict;
use Fcntl qw(:DEFAULT :flock);

&initialise;
my ($query)     = new CGI;
print $query->header if $DEBUG;

if ($query->param('zserver')) { # User has entered zserver parameters.
  $zserver = $query->param('zserver');

  undef $query;

        # Print the HTML header
  my ($q) = new CGI;
  print $q->header;

        # Check flock if flock send sorry being used wait
  open (LOCKFILE, "> $lockFile") or die "Can't open the lockfile
$lockFile:$!\n"
;
  if (flock (LOCKFILE, LOCK_EX | LOCK_NB)) {
    &processSite();
    flock (LOCKFILE, LOCK_UN);
    unlink $lockFile;
  } else {
    &printBusy;
  }
  undef $q;
  exit (0);

} else {        # First time to this page so print HTML form.
  my ($q) = new CGI;
  print $q->header;
  &printInputPage;
  undef $q;
  exit (0);
}

Thanks again for all your help.


John

> -----Original Message-----
> From: Paul Fenwick [mailto:pjf at perltraining.com.au] 
> Sent: Friday, 29 July 2005 10:55 AM
> To: Hockaday John
> Cc: canberra-pm at pm.org
> Subject: Re: [Canberra-pm] How to flock a file for to ensure 
> only one CGI BIN script process at a time
> 
> 
> G'day John,
> 
> John.Hockaday at ga.gov.au wrote:
> 
> [snip]
> 
> > I thought that flock would be the best method to use a lock 
> file to stop any
> > other users from  running the script while someone else has 
> it running.  The
> > trouble is that the script creates the lockFile and doesn't 
> delete it.  How
> > can I get flock to check if the lockFile exists and if so 
> send a busy message
> > to CGI.  Otherwise, set the lockFile, flock it and process the site?
> 
> If I understand you correctly, you only want a single copy of 
> the CGI to be
> executing at once.  The easy way to do this isn't to create a 
> separate lockfile,
> but to instead lock your program itself.  These are described 
> in MJD's "Locking
> Tricks and Traps" that can be found at 
> http://perl.plover.com/yak/flock/ .
> 
> In a nutshell:
> 
> 	use Fcntl qw(:flock);
> 
> 	open(SELF, "< $0") or die "Cannot open $0 - $!\n";
> 
> 	flock(SELF, LOCK_EX | LOCK_NB) or die "Already running\n";
> 
> 	__END__
> 
> alternatively:
> 
> 	flock(DATA, LOCK_EX | LOCK_NB) or die "Already Running\n";
> 
> 	# ...
> 
> 	__DATA__
> 
> By opening and locking your own source file, you save all the 
> hassle of trying
> to co-ordinate lockfile creation and deletion.
> 
> All this assumes that you're running on a single machine, and 
> not a farm of
> machines.  Locking over a network filesystem has other hazards.
> 
> Cheerio,
> 
> 	Paul
> 
> -- 
> Paul Fenwick <pjf at perltraining.com.au> | http://perltraining.com.au/
> Director of Training                   | Ph:  +61 3 9354 6001
> Perl Training Australia                | Fax: +61 3 9354 2681
> 


More information about the Canberra-pm mailing list