gpt4 book ai didi

linux - 出现错误时释放 flock?

转载 作者:IT王子 更新时间:2023-10-28 23:52:03 26 4
gpt4 key购买 nike

想象以下 Perl 代码(此处为伪代码):

successfully acquired flock for FILEHANDLER       # line 1
some error or maybe simply a call to exit() # line 2
close FILEHANDLER (which also releases the lock) # line 3

在这种情况下,我不会释放锁,因为 Perl 脚本在第 2 行结束。在这种情况下,操作系统是否释放过锁?它是否看到“嘿,获取锁的脚本崩溃了”并释放了锁?它会立即释放锁吗?另外,每个脚本是否运行一个 Perl 实例,以便清楚哪个脚本在未释放锁的情况下崩溃/停止?

最佳答案

In that case, is the lock ever released by the operating system?
Does it see "hey, the script that acquired the lock crashed" and release the lock?
Does it release the lock immediately?

所有这些问题都取决于系统。 Perl 5 没有实现文件锁定功能,它只是为flock(2)fcntl(2) 锁定或lockf(3) 提供了一个通用接口(interface)(取决于操作系统中可用的内容)。程序退出、段错误或被 sigkill 终止时发生的情况也可能有所不同。

在 Linux 下的快速测试表明,在正常退出条件下会移除锁:

$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"'
got lock

让我们看看当我们时会发生什么:

$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.
$ perl -le 'open my $fh, ">", "f" or die $!; print flock($fh, 6) ? "got lock" : "was already locked", "\n"; die "died"'
got lock
died at -e line 1.

要获得段错误,我们需要访问 C,我正在使用 Inline 来获得它:

$ cat segfault.pl
#!/usr/bin/perl

use strict;
use warnings;

use Inline "C";

open my $fh, ">", "f" or die $!;

print flock($fh, 6) ? "got lock" : "was already locked", "\n";

crash();

__DATA__
__C__

void crash() {
int* ptr = NULL;
*ptr = 5;
}
$ perl segfault.pl
got lock
Segmentation fault
$ perl segfault.pl
got lock
Segmentation fault

最后,这是发送程序 SIGKILL 时发生的情况:

$ cat fork.pl
#!/usr/bin/perl

use strict;
use warnings;

$SIG{CHLD} = "IGNORE"; #auto-reap children

die "could not fork: $!" unless defined(my $pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
sleep(100);
exit;
}

kill 9, $pid;

die "could not fork: $!" unless defined($pid = fork);
unless ($pid) {
#child
open my $fh, ">", "f" or die $!;
print flock($fh, 6) ? "got lock" : "was already locked", "\n";
exit;
}
$ perl fork.pl
got lock
got lock

从这些实验中,我们可以看到对于您所关注的每种情况,Linux 中的锁都会被释放。

Also, is there one perl instance running for each script, so that it's clear which script crashed/stopped without releasing the lock?

是的,Perl 5 每个脚本有一个 perl 进程。即使您 fork,子进程也会获得自己的 perl 进程。线程不提供单独的 perl 进程。

注意:如果一个父进程得到了一把锁,并且在加锁前没有放弃,那么即使父进程退出,子进程也会拥有同样的锁。

关于linux - 出现错误时释放 flock?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12651068/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com