10

G'day Stackoverflowers,

我是 Perl 的autodie pragma 的作者,它改变了 Perl 的内置函数以在失败时抛出异常。它类似于Fatal,但具有词法范围、可扩展的异常模型、更智能的返回检查以及更好的错误消息。它将Fatal在 Perl 的未来版本(临时 5.10.1+)中替换该模块,但目前可以从 Perl 5.8.0 及更高版本的 CPAN 下载。

下一个版本autodieflock使用LOCK_NB(非阻塞)选项添加对调用的特殊处理。虽然失败的flock调用通常会导致 under 的异常,但如果返回的 errno( ) 为,则对usingautodie的失败调用只会返回 false 。flockLOCK_NB$!EWOULDBLOCK

这样做的原因是人们可以继续编写如下代码:

use Fcntl qw(:flock);

use autodie;   # All perl built-ins now succeed or die.

open(my $fh, '<', 'some_file.txt');

my $lock = flock($fh, LOCK_EX | LOCK_NB);  # Lock the file if we can.

if ($lock) {
    # Opportuntistically do something with the locked file.
}

EWOULDBLOCK在上面的代码中,由于其他人已经锁定了文件flock(在我们正在使用不支持文件锁的文件系统或网络文件系统并且网络刚刚死机的情况下,当自动染色flock发现我们的 errno 不是时,它会生成一个适当的异常EWOULDBLOCK

这在我的 Unix 风格系统上的开发版本中运行良好,但在 Windows 下却严重失败。看起来虽然 Windows 下的 Perl 支持该LOCK_NB选项,但它没有定义EWOULDBLOCK. 相反,当发生阻塞时,返回的 errno 是 33(“域错误”)。

显然我可以将它作为一个常量硬编码到autodie中,但这不是我想要在这里做的,因为这意味着如果 errno 改变(或已经改变),我会搞砸的。我很想将它与 Windows 等效的POSIX::EWOULDBLOCK. 如果你能帮忙,请告诉我。

我特别不想要的答案:

  • 建议将其硬编码为常数(或者更糟糕的是,留下一个浮动的幻数)。
  • 在 Windows 下根本不支持LOCK_NB功能。
  • 假设LOCK_NB调用的任何失败flock都应仅返回 false。
  • 我在 p5p 或perlmonks上提出的建议。我已经知道他们了。
  • 解释如何flock,或异常,或Fatal工作。我已经知道了。亲密无间。
4

2 回答 2

11

在 Win32“本机”Perl 下,请注意 $^E 在 33 处更具描述性,“进程无法访问文件,因为另一个进程锁定了文件的一部分” ERROR_LOCK_VIOLATION(可从Win32::WinError 获得)。

于 2008-09-25T06:58:17.043 回答
5

对于 Windows 特定的错误代码,您要使用$^E. 在这种情况下,它是 33:“该进程无法访问该文件,因为另一个进程已锁定文件的一部分”(ERROR_LOCK_VIOLATIONin winerror.h)。

不幸的是,我不认为Win32::WinError是核心。另一方面,如果微软对 Windows 错误代码重新编号,几乎所有编写的 Windows 程序都会停止工作,所以我认为硬编码不会有问题。

于 2008-09-25T07:14:05.773 回答