How to prevent a Perl script from running more than once in parallel

流过昼夜 提交于 2019-12-11 01:34:46

问题


I have a script that potentially runs for a long time. On Linux. While it is running, when invoked a second time by the same or a different user, it should detect that and refuse to run. I'm trying to figure out how to create a suitable semaphore that gets cleaned up even if the process dies for some reason.

I came across How to prevent PHP script running more than once? which of course can be applied, but I wondering whether this can be done better in Perl.

For example, Perl has the "clean up created temp file at process exit" flag (File::Temp::CLEANUP) that I believe triggers regardless how the process ended. But this API can only be used for creating temp files that have randomized names, so it won't work as a file name for a semaphore. I don't understand the underlying mechanism for how the file gets removed, but is sounds like the mechanism exists. How would I do this for a named file, e.g. /var/run/foobar?

Or are there better ways of doing this?


回答1:


use strict;
use warnings;
use Fcntl ':flock';

flock(DATA, LOCK_EX|LOCK_NB) or die "There can be only one! [$0]";


# mandatory line, flocking depends on DATA file handle
__DATA__



回答2:


One method is to put the pid in the file, then you can have the script check the running process.

open(my $fh, '>', '/var/run/foobar');
print $fh "$$\n";
close $fh;

Then you can read it with:

if (open(my $fh, '<', '/var/run/foobar')) {
    while (my $PID = <$fh>) {
        chomp $PID;
        $proc = `ps hp $PID -o %c`;
        if ($proc eq "foobar"){
            exit();
        }
        break;
    }
}

Probably want to do those in the other order



来源:https://stackoverflow.com/questions/27433252/how-to-prevent-a-perl-script-from-running-more-than-once-in-parallel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!