当前位置:  开发笔记 > 编程语言 > 正文

如何在Perl中锁定文件?

如何解决《如何在Perl中锁定文件?》经验,为你挑选了5个好方法。

在Perl中创建文件锁的最佳方法是什么?

最好是聚集文件或创建锁定文件以锁定并检查锁定文件上的锁定?



1> Chris Bunch..:

如果你最终使用flock,这里有一些代码:

use Fcntl ':flock'; # Import LOCK_* constants

# We will use this file path in error messages and function calls.
# Don't type it out more than once in your code.  Use a variable.
my $file = '/path/to/some/file';

# Open the file for appending.  Note the file path is quoted
# in the error message.  This helps debug situations where you
# have a stray space at the start or end of the path.
open(my $fh, '>>', $file) or die "Could not open '$file' - $!";

# Get exclusive lock (will block until it does)
flock($fh, LOCK_EX) or die "Could not lock '$file' - $!";

# Do something with the file here...

# Do NOT use flock() to unlock the file if you wrote to the
# file in the "do something" section above.  This could create
# a race condition.  The close() call below will unlock the
# file for you, but only after writing any buffered data.

# In a world of buffered i/o, some or all of your data may not 
# be written until close() completes.  Always, always, ALWAYS 
# check the return value of close() if you wrote to the file!
close($fh) or die "Could not write '$file' - $!";

一些有用的链接:

PerlMonks文件锁定教程(有点旧)

flock() 文件

为了回答您添加的问题,我要么说锁定在文件上,要么创建一个文件,当文件被锁定时你称之为'lock',当它不再被锁定时删除它(然后确保你的程序服从那些语义).



2> Alex Dupuy..:

其他答案很好地涵盖了Perl flock,但在许多Unix/Linux系统上实际上有两个独立的锁定系统:BSD flock()和基于POSIX fcntl()的锁.

除非在构建Perl时提供配置的特殊选项,否则它的flock将使用flock()(如果可用).这通常很好,如果您只需要在应用程序中锁定(在单个系统上运行),可能就是您想要的.不过,有时你需要与使用的fcntl()锁(如sendmail,在许多系统上),或者你需要做的文件通过NFS安装的文件系统锁定另一个应用程序进行交互.

在这些情况下,您可能希望查看File :: FcntlLock或File :: lockf.也可以在纯Perl中执行基于fcntl()的锁定(带有一些有毛和非便携的pack()).

flock/fcntl/lockf差异的快速概述:

lockf几乎总是在fcntl之上实现,只有文件级锁定.如果使用fcntl实现,则以下限制也适用于lockf.

fcntl提供范围级锁定(在文件中)和NFS上的网络锁定,但fork()之后子进程不会继承锁.在许多系统上,您必须将文件句柄打开为只读以请求共享锁,并使用读写来请求独占锁.

flock只有文件级锁定,锁定只在一台机器内(你可以锁定一个NFS挂载的文件,但只有本地进程才会看到锁定).锁由子进程继承(假设文件描述符未关闭).

有时(SYSV系统)flock是使用lockf或fcntl模拟的; 在一些BSD系统上,使用flock模拟lockf.通常这些类型的仿真效果很差,建议您避免使用它们.


感谢对底层系统调用之间的一些区别的精细解释.维基百科的[Unix文件锁定问题列表](http://en.wikipedia.org/wiki/File_locking#Problems)可能需要阅读.

3> Gary Richard..:

CPAN救援:IO :: LockedFile.



4> Aristotle Pa..:

Ryan P写道:

在这种情况下,文件在重新打开文件时实际上会在短时间内解锁.

所以不要这样做.相反,open读/写文件:

open my $fh, '+<', 'test.dat'
    or die "Couldn’t open test.dat: $!\n";

当您准备好编写计数器时,只需seek返回文件的开头即可.请注意,如果您这样做,您应该truncate在之前close,以便如果文件的新内容比以前的内容短,则文件不会留下尾随垃圾.(通常,文件中的当前位置在最后,所以你可以写truncate $fh, tell $fh.)

另外,请注意我使用了三个参数open和一个词法文件句柄,我还检查了操作是否成功.请避免全局文件句柄(全局变量是坏的,mmkay?)和魔术双参数open(它是Perl代码中许多(n可利用的)错误的来源),并且总是测试你open的成功是否成功.



5> szabgab..:

我认为将词法变量显示为文件处理程序和错误处理会更好.使用Fcntl模块中的常量也比使用魔术数字2的硬编码更好,这可能不是所有操作系统上的正确数字.

    use Fcntl ':flock'; # import LOCK_* constants

    # open the file for appending
    open (my $fh, '>>', 'test.dat') or die $!;

    # try to lock the file exclusively, will wait till you get the lock
    flock($fh, LOCK_EX);

    # do something with the file here (print to it in our case)

    # actually you should not unlock the file
    # close the file will unlock it
    close($fh) or warn "Could not close file $!";

查看flock的完整文档和PerlMonks上的文件锁定教程,即使它也使用了旧式的文件句柄用法.

实际上我通常会跳过close()上的错误处理,因为如果它失败了我无能为力.

关于要锁定的内容,如果您在单个文件中工作,则锁定该文件.如果您需要同时锁定多个文件,那么 - 为了避免死锁 - 最好选择一个锁定的文件.如果这是您真正需要锁定的几个文件之一,或者您为锁定目的而创建的单独文件,这并不重要.


无论如何你应该检查'close`.你不能做太多,但你至少可以告诉用户并拯救,而不是默默地继续运行,好像什么也没发生过.
推荐阅读
夏晶阳--艺术
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有