Here's one way
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11148582
use warnings;
use Time::HiRes qw( sleep );
sub grabthelockorexit
{
my $lockfilename = '/tmp/d.11148582.lockfile'; # FIXME to your filen
+ame
open our $fh, '>>', $lockfilename or die "$! on $lockfilename";
use Fcntl qw(:flock);
flock $fh, LOCK_EX | LOCK_NB or die "$$ exiting $!\n";
}
# The following is just test code
for (1 .. 9)
{
if( my $pid = fork )
{
sleep 0.33;
}
elsif( defined $pid )
{
sleep 0.1 + rand( 0.1 );
grabthelockorexit();
print "$$ got lock\n";
sleep 1; # FIXME body of code...
print "$$ exiting\n";
exit;
}
else { die "fork failed" }
}
1 while wait > 0; # wait until all children finish
I'm just using fork for test purposes starting a new process at 3 per second.
Just put the sub in your code and call it at/near the beginning and it will flock or exit.
No need to write anything to the file or remove it after your code exits.
You could also put the code from the sub in-line if you want to.
If your processes crashes, no cleanup is required. Using '>>' will create the file if it does not exist or just open it if it does.
This works fine on my ArchLinux, should work the same on your Ubuntu.
Outputs (for sample run):
79504 got lock
79505 exiting Resource temporarily unavailable
79506 exiting Resource temporarily unavailable
79509 exiting Resource temporarily unavailable
79504 exiting
79510 got lock
79511 exiting Resource temporarily unavailable
79514 exiting Resource temporarily unavailable
79510 exiting
79515 got lock
79516 exiting Resource temporarily unavailable
79515 exiting