Perl 在多服务器上下文中使用 Fcntl
Perl using Fcntl in multi server context
我正在尝试使用 Fcntl 库 运行 一次只有一个脚本实例,
只有一台服务器 运行 脚本时有效(同一台服务器不能 运行 脚本的另一个实例),但如果我有 另一个 服务器(实际上访问同一个文件系统)运行 脚本,它不起作用(他实际上可以 运行 它)。
任何人都知道如何使用 Fcntl 库(或另一个?)来处理这个问题
提前致谢。
众所周知,文件锁定比 NFS 更难,但对于您的需要来说,它可能有点矫枉过正。只需让服务器实例在网络可访问的文件上进行协调,该文件将包含有关带有 "lock".
的服务器的信息
...
if (-f "/network/accessible/file.lock") {
open my $fh, '<', "/network/accessible/file.lock";
my $lockholder = <$fh>;
die "Server lock held by $lockholder";
# ... you could also examine $lockholder and verify that
# the other server is still alive ...
} else {
open my $fh, '>', "/network/accessible/file.lock";
print $fh $ENV{HOSTNAME},":$$";
close $fh;
}
...
# need to remove the lock when the current server finishes
END { unlink "/network/accessible/file.lock" }
除非您在几毫秒内启动两个服务器,否则这就足够了。如果您对此疑虑重重,可以让服务器在创建锁定文件后读取它,and/or 在整个程序中定期读取,以确保锁定文件信息未更改。
} else {
open my $fh, '>', "/network/accessible/file.lock";
print $fh $ENV{HOSTNAME},":$$";
close $fh;
sleep 1;
open $fh, '<', "/network/accessible/file.lock";
my $lockholder = <$fh>;
if ($lockholder ne "$ENV{HOSTNAME}:$$") {
die "Server lock was stolen by $lockholder!";
}
}
我正在尝试使用 Fcntl 库 运行 一次只有一个脚本实例,
只有一台服务器 运行 脚本时有效(同一台服务器不能 运行 脚本的另一个实例),但如果我有 另一个 服务器(实际上访问同一个文件系统)运行 脚本,它不起作用(他实际上可以 运行 它)。
任何人都知道如何使用 Fcntl 库(或另一个?)来处理这个问题
提前致谢。
众所周知,文件锁定比 NFS 更难,但对于您的需要来说,它可能有点矫枉过正。只需让服务器实例在网络可访问的文件上进行协调,该文件将包含有关带有 "lock".
的服务器的信息...
if (-f "/network/accessible/file.lock") {
open my $fh, '<', "/network/accessible/file.lock";
my $lockholder = <$fh>;
die "Server lock held by $lockholder";
# ... you could also examine $lockholder and verify that
# the other server is still alive ...
} else {
open my $fh, '>', "/network/accessible/file.lock";
print $fh $ENV{HOSTNAME},":$$";
close $fh;
}
...
# need to remove the lock when the current server finishes
END { unlink "/network/accessible/file.lock" }
除非您在几毫秒内启动两个服务器,否则这就足够了。如果您对此疑虑重重,可以让服务器在创建锁定文件后读取它,and/or 在整个程序中定期读取,以确保锁定文件信息未更改。
} else {
open my $fh, '>', "/network/accessible/file.lock";
print $fh $ENV{HOSTNAME},":$$";
close $fh;
sleep 1;
open $fh, '<', "/network/accessible/file.lock";
my $lockholder = <$fh>;
if ($lockholder ne "$ENV{HOSTNAME}:$$") {
die "Server lock was stolen by $lockholder!";
}
}