当前位置: 首页 > 面试题库 >

发生错误时释放羊群?

谢运良
2023-03-14
问题内容

想象以下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实例,以便清楚地知道哪个脚本崩溃/停止而不释放锁?


问题答案:

在那种情况下,操作系统是否释放过该锁?
它是否看到“嘿,获取锁的脚本崩溃了”并释放了锁?
它会立即释放锁吗?

所有这些问题都取决于系统。Perl
5并没有实现文件锁定功能,它只是提供了flock(2)fcntl(2)锁定或lockf(3)(取决于OS中可用的功能)的通用接口。程序退出,segfaults或被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

让我们看看当我们die

$ 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中释放了该锁。

另外,是否为每个脚本运行一个perl实例,以便清楚地知道哪个脚本崩溃/停止而没有释放锁?

是的,Perl 5 perl每个脚本只有一个进程。即使您分叉,孩子也会有自己的perl过程。线程不提供单独的perl过程。

注意:如果父进程获得了锁并且在锁之前没有放弃,那么即使父进程退出,子进程也将拥有相同的锁。



 类似资料:
  • 我正在unity3d 5.3.5上开发android应用程序,我在将应用程序构建到apk时没有遇到任何问题。我添加了windows模块,将项目切换到windows,并成功构建了项目。我切换回Android系统,当我尝试构建项目时,我发现了错误: > 错误构建播放器:反射类型加载异常:模块中的类无法加载。 反射类型加载异常:模块中的类无法加载。系统。反射。汇编。GetTypes()(在 /Users

  • 问题内容: 我正在尝试在Java和其中一种格式上播放mp3音频。我相信是JavaFX,一切正常,直到尝试播放音频为止。 这是代码: 当我按下按钮并尝试加载声音文件时,出现此异常: 如何解决错误?单击后是否要播放音频文件? 问题答案: Media的构造函数需要一个URL,因此您需要以http://或file://开头的内容 参见http://docs.oracle.com/javase/8/java

  • 我有一个包含在API中的Spring Boot应用程序。它公开了一个endpoint。在引擎盖下,Spring靴附带了Hibernate和Hikaricp。我的数据库是PostgreSQL 10。该应用程序是在Kotlin中构建的。 当API同时接收请求时,我发现了一个问题,似乎应用程序需要2个活动连接来执行endpoint调用的操作。 我面临的问题是,在那之后,HikariCP仍然说池上有5个活

  • 无法生成pdf下载获取Android.os.fileuriexposedexception错误:file:///storage/emulated/0/download/inv-0002.pdf通过intent.getdata()超出应用程序公开

  • 我是拉威尔的新手,所以你可能不得不忍受我,但我似乎有个小问题。现在,首先,我创建了一个基本模板,并使用phpMyAdmin和Wamp成功地运行了它,它运行得很好。我还得到了一个老项目,我被要求看一看,但由于某种原因,我无法让它运行。 这就是我正在使用的过程: 1:打开cmd更改到正确的目录 2:安装编写器 3:将目录更改为项目目录 4:运行 错误: PHP警告:需要(C:\wamp64\www\p

  • 我不知道该怎么办!感谢任何帮助! 另外,我是否应该在安装HBase之前配置Zookeeper?我的教程没有这么说。