检测文件夹中的文件正在被复制



我正在运行一个脚本,该脚本从特定位置复制一个文件夹,如果它不存在(或不一致)。当我同时运行脚本2+次时,问题就出现了。当第一个脚本试图复制文件时,第二个脚本来了,并尝试同样的事情,导致混乱。我怎样才能避免这种情况呢?类似于系统级互斥锁。

我尝试了一个简单的测试与-w,我手动复制文件夹,而文件夹正在复制我运行脚本:

use strict;
use warnings;
my $filename = 'd:\folder_to_copy';
if (-w $filename) {
  print "i can write to the filen";
} else {
  print "yikes, i can't write to the file!n";
}

当然不行,因为我仍然有对那个文件夹的写权限。我该如何检查文件夹是否在Perl中复制或使用batch commands ?

听起来像是锁文件的工作。有无数的CPAN模块实现了锁文件,但它们中的大多数都不能在Windows上工作。根据CPAN测试人员的说法,以下是一些似乎支持Windows的应用程序:

  • <罢工>文件:Lockfile罢工
  • <罢工>文件:TinyLock罢工
  • 文件::群::小

快速查看源代码后,我可以推荐的唯一模块是File::Flock::Tiny

如果您需要一个系统范围的互斥锁,那么一个"技巧"是(ab)使用目录。命令mkdir通常是原子的,可以工作,也可以不工作(如果目录已经存在)。

修改脚本如下:

my $mutex_dir = '/tmp/my-mutex-dir';
if ( mkdir $mutex_dir ) {
    # run your copy-code here
    # when finished:
    rmdir $mutex_dir;
} else {
    print "another instance is already running.n";
}

你唯一需要确保的是你被允许在/tmp(或任何地方)创建一个目录。

注意,我故意让NOT首先测试$mutex_dir是否存在,因为在if (not -d $mutex_dir)mkdir之间,其他人可以创建目录,而mkdir无论如何都会失败。所以只需调用mkdir。如果成功了,你就可以做你的事了。完成后不要忘记移除$mutex_dir

这也是这种方法的缺点:如果复制代码崩溃并且脚本过早死亡,则不会删除目录。在这种情况下,nwellhof的答案中建议的锁文件机制可能会表现得更好,并自动解锁文件。

当第一个脚本试图复制文件时,第二个脚本来了尝试同样的事情导致混乱

最简单的方法是创建一个文件,如果另一个脚本实例正在运行,该文件将包含1。然后你可以在此基础上添加一个条件。

{local $/; open my $fh, "<", 'flag' or die $!; $data = <$fh>};
die "another instance of script is running" if $data == 1;

另一种方法是在脚本中设置环境变量,并在BEGIN块中检查它。

您可以使用该包的windows互斥对象或windows信号量对象http://search.cpan.org/cjm/win32 - ipc - 1.11/

use Win32::Mutex;
use Digest::MD5 qw (md5_hex);
my $mutex = Win32::Mutex->new(0, md5_hex $filename);
if ($mutex) {
     do_your_job();
     $mutex->release
} else {
     #fail...
}

相关内容

  • 没有找到相关文章

最新更新