如何确保一次只运行一份 Perl 脚本副本?

发布于 2024-09-27 17:18:11 字数 353 浏览 1 评论 0原文

我需要确保一次只运行一份 Perl 脚本副本。根据建议此处我编写了一个子程序来进行检查:

sub check_instances {
    open my $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}

但它不起作用。可能是什么问题?

I need to ensure that only one copy of my Perl script is running at a time. According to the suggestions here I wrote a sub to do the check:

sub check_instances {
    open my $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}

But it doesn't work. What can be the issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

花海 2024-10-04 17:18:11

您正在使用子范围内的词法文件句柄。当 check_instances 返回时,文件句柄会自动关闭,从而释放锁。因此,除非两个副本完全相同地同时检查,否则您永远不会看到冲突。

确保只要脚本正在运行(或者只要您想要保持锁定),文件句柄就保持打开状态。例如:

{
my $fh;
sub check_instances {
    return if $fh; # We already checked
    open $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}
} # end scope of $fh

这也是使用 state 变量< /a>,如果您需要 Perl 5.10。

You're using a lexical filehandle scoped inside the sub. When check_instances returns, the filehandle is automatically closed, which releases the lock. So you'll never see a conflict unless two copies check at exactly the same time.

Ensure that the filehandle remains open as long as the script is running (or as long as you want to maintain the lock). For example:

{
my $fh;
sub check_instances {
    return if $fh; # We already checked
    open $fh, '<', $0 or die $!; 

    unless (flock($fh, LOCK_EX|LOCK_NB)) {
        print "$0 is already running. Exiting.\n";
        exit 1;
    } 
}
} # end scope of $fh

This would also be a good place to use a state variable, if you can require Perl 5.10.

他不在意 2024-10-04 17:18:11

您可以检查其他实例的进程列表(Proc::ProcessTable 可以提供帮助) ,但许多语言中的 UNIX 程序采用的常见途径是创建 pid 文件 - 请参阅 文件::Pid

You can check the process list for other instances (Proc::ProcessTable can help), but a common route taken by unix programs in many languages is to create a pid file -- see File::Pid.

双手揣兜 2024-10-04 17:18:11

flock 的正常语义可能要求您以写入模式打开文件句柄,例如

open $fh, '>>', $0;
open $fh, '+<', $0;

(来自 perldoc -f集群

请注意,flock(3) 的 fcntl(2) 模拟要求:
FILEHANDLE 以读取意图打开以使用 LOCK_SH 并要求
它以写入意图打开以使用 LOCK_EX。

The normal semantics of flock may require you to open the filehandle in write mode, say,

open $fh, '>>', $0;
open $fh, '+<', $0;

(From perldoc -f flock)

Note that the fcntl(2) emulation of flock(3) requires that
FILEHANDLE be open with read intent to use LOCK_SH and requires
that it be open with write intent to use LOCK_EX.

她比我温柔 2024-10-04 17:18:11

文件锁定可能会因各种原因而失败(例如,如果文件位于 NFS 等网络文件系统上)。

我的解决方案是在脚本运行时创建一个目录。创建目录始终是一个原子操作。

File locking can fail for various reasons (for example if the file is on a network file system like NFS).

My solution is to create a directory while the script runs. Creating directories is always an atomic operation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文