使用Fcntl锁定文件:涉及“使用”和“要求”的令人困惑的错误

下面的 Perl 脚本输出“成功”,正如你所期望的:

的 Perl 脚本输出“成功”,正如你所期望的:

use Fcntl qw(:DEFAULT :flock);
sysopen(LF, "test.txt", O_RDONLY | O_CREAT) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX)) { print "SUCCESS.\n"; }
else { print "FAIL: $!\n"; }

但是现在,将第一行替换为

require "testlib.pl";

其中 testlib.pl 包含

use Fcntl qw(:DEFAULT :flock);
1;

现在,奇怪的是,脚本失败,像这样:

FAIL: Bad file descriptor

问题:为什么?

已添加:

现在我知道为什么了-谢谢!-我想知道解决此问题的最佳方法是什么:

只需执行use Fcntl两次,一次在主脚本中,一次在所需的库中(主脚本和库都需要它)。

将 O_RDONLY 替换为 & amp;O_RDONLY 等。

将 O_RDONLY 替换为 O_RDONLY () 等。

还有别的吗?

3

通过前面的use,您剥夺了 Perl 解析器的知识O_RDONLY等。是无参数的子例程。在这种情况下,您必须更加详细:

sysopen(LF, "test.txt", O_RDONLY() | O_CREAT()) or die "SYSOPEN FAIL: $!";
if(flock(LF, LOCK_EX())) { print "SUCCESS.\n"; }

编辑:为了进一步阐述,没有括号,O_RDONLYO_CREAT被解释为 barewords(字符串),当二进制或 'ed 在一起时,它们的行为不像你期望的那样:

$ perl -le 'print O_RDONLY | O_CREAT'
O_SVOO\Y

(各个字符按位或拼在一起。)

在这种情况下,字符串“O_SVOO\ Y”(或您系统上的任何内容)被解释为数字 0 到sysopen,因此只要O_RDONLY为 0(通常)并且文件已经存在(因此O_CREAT是多余的)。但是fcntl显然不是数字非参数

$ perl -e 'flock STDOUT, "LOCK_EX" or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.

同样:

$ perl -e 'flock STDOUT, LOCK_EX or die "Failed: $!"'
Failed: Bad file descriptor at -e line 1.

然而:

$ perl -e 'use Fcntl qw(:flock); flock STDOUT, LOCK_EX or die "Failed: $!"'
(no output)

最后,请注意use strict提供了许多有用的线索。

2

然后,行use Fcntl qw(:DEFAULT :flock);不仅为您加载 Fcntl 库,而且还将一些符号导出到脚本的命名空间中。如果将其移动到不同的范围,则常量 O_RDONLY,O_CREAT,LF 和 LOCK_EX 将不再对您可用,并且您的代码不会做同样的事情[但是您仍然可以访问它们,因为它们是 AME-

这在EXPORTED SYMBOLS下的文档中有描述:

默认情况下,系统的 F_* 和 O_* 常量(例如 F_DUPFD 和 O_CREAT)以及 FD_CLOEXEC 常量将导出到您的命名空间中。

您可以使用标记“:flock”请求提供 flock () 常量(LOCK_SH 、 LOCK_EX 、 LOCK_NB 和 LOCK_UN)。请参见 Exporter。

如果添加行

use strict;
use warnings;

到你的脚本的顶部,你会得到更多的信息性错误消息,如“名称”main::O_RDONLY“只使用一次:可能的类型在行...”,这将给你一个线索,这些常量定义不再可见。

编辑:为了回答你的问题,最好的做法是 # 1,在每个需要它的文件中包含 use 语句。请参阅perldoc -f use-Fcntl 库只包含一次,但每次需要时都会进行 import()调用,这就是你想要的。

0

使用相当于:

BEGIN { require Module; Module->import( LIST ); }

保证导入函数在代码开始执行之前可用。当您用 require 替换 use 时,它只是在程序中存在的词法点读取代码。

本站系公益性非盈利分享网址,本文来自用户投稿,不代表码文网立场,如若转载,请注明出处

(155)
需要 Excel表格来计算复杂的假期应计和假期时间的使用
上一篇
在Java中使用for循环绘制围栏
下一篇

相关推荐

发表评论

登录 后才能评论

评论列表(87条)