Yes you absolutely need to remove the lockfile, so leave the unlink. The point of the question is that a lockfile is a semaphore - is says (to other code, usually including other instances of itself) hang on everyone, I am using this file/dir/process. When I am done I will delete the lockfile so why don't you just wait around until I am done, then you can create a lockfile and have x/y/z to yourself.
One problem with lockfiles and CGI is that if a CGI process starts, creates the lockfile but dies before it deletes it (user presses stop button for instance) the lockfile remains and will never get deleted. For this reason flocking a filehandle is often preferred. This way you process gets the exclusive aceess it wants but the lock is released when the process dies, FH goes out of scope.....
One typical use of lockfiles is to stop two instances of a process starting. The first thing the process does is check for the lockfile and refuses to start if it exists. This is fine provided the lockfile always gets removed. What if the process that created it dies before removing the lockfile......You either have to delete it by hand or do something like this:
#!/usr/bin/perl -w $|++; use strict; use Fcntl; use POSIX qw(setsid); my $PROGRAM = 'cleaner.pl'; my $LOCKFILE = "/var/lock/$PROGRAM"; # use a lockfile to prevent spawning duplicate processes unless ( sysopen(my $fh, $LOCKFILE, O_CREAT | O_EXCL | O_RDWR, 0600) ) + { close $fh; # the lockfile already exists print "Lockfile $LOCKFILE aready exists.\nChecking for running $PR +OGRAM process..."; # sleep for a couple of seconds to make sure we don't race # by this time the process should be in the process table sleep 2; my @ps = grep{ m/\Q$PROGRAM\E/ } `ps -C $PROGRAM`; # we expect 1 copy (us) running # print "@ps\n"; die "\nThere is already a copy of $PROGRAM running!\n" if @ps > 1; print "None!\n"; } # now demonize it defined(my $pid = fork) or die "Can't fork: $!"; exit 0 if $pid; chdir '/' or die "Can't chdir to /: $!"; umask 0; setsid() or die "Can't start a new session: $!"; $SIG{INT} = $SIG{TERM} = sub { unlink $LOCKFILE or warn "Could not unlink $LOCKFILE for $PROGRAM\ +n"; $dbh->disconnect if $dbh; exit; }; $SIG{HUP} = sub { warn "Caught HUP " . time() . "\n"; }; print "Started $0 daemon OK\n\n"; open STDIN, '/dev/null' or die "Can't read /dev/null: $!"; open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!"; open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!"; # this is the main loop that runs forever, once every 30 seconds # we don't want to die so we eval our function in case it chokes # we have closed STDERR so we won't know if it is choking # but we can change the code as required for debugging. while (1) { eval{ blah() }; sleep 30; }
Here is some unix demon process code we use. You will note that it recovers from the dead lockfile issue using the following logic. If the lockfile exists*, also ensure that the process that created it exists. If we have a lockfile but no 'parent' process assume abnormal termination and start a new instance.
* Actually it does not check for lockfile existence in the way you might expect. It actually tries to create it with an exclusive lock - provided the perms are OK this will only fail if it already exists. You could do this:
unless ( -e $lockfile ) { open F, ">$lockfile" or die; }
However there is a race condition here as there is a small but real delay between checking if the lockfile exists and creating it. It is therefore possible that two process could check for a lockfile at the exact same time, find it absent and this create it. The sysopen method is ATOMIC and thus avoids this rare but real problem. It is atomic because the existence check and creation happen as a single operation that either succeeds or fails.
Note the signal handlers that let us unlink the lockfile if we get an INT or TERM signal before we exit.....
cheers
tachyon
s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print
In reply to Re: Re: Re: Re: Re: Perl script crashing at lockfile ?
by tachyon
in thread Perl script crashing at lockfile ?
by peterr
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |