2012-05-14 114 views
0

我有一个子例程,其中我试图专门锁定一组文件(一次一个),并保持一定的给定时间(通过sleep)的锁定。我试图添加让用户在按下某个键(如回车键)时解锁当前锁定(睡眠)文件的功能。我只是不确定要采取什么方向来实现这一目标。每次尝试使用STDIN并检查\ n都无效。谢谢。从输入文件锁定和解锁

下面是子程序。我切换到我想要这些文件的目录。从1创建文件以指定多少个文件。对于每个文件,放置一个独占锁,然后休眠指定的时间量。

编辑:这是我的错,没有提到这个,但是,这个脚本将在Windows环境中运行。我最好喜欢一个不需要附加模块安装但不包含在Perl中的解决方案。 (这是因为breq中的模块解决方案不支持Windows)。谢谢。

sub lockFiles{ 
    #creates files that are locked for a specific amount of seconds. 
    chdir("lock files")or die "Unable to enter dir $!\n"; 
    opendir(DIR,".") or die "Can't open the current directory: $!\n"; 

    #file iterator 
    my $i=1; 
    #for each file lock it and sleep the given amount of time 
    while($i<=$numberOfFiles){ 
     open FILE, ">>", "test$i.txt" or die $!; 
     flock(FILE, 2) or die "Could not lock test$i.txt\n"; 
     print "test$i.txt locked, locking for $timeToSleep seconds\n"; 
     print "Press ctrl+c to kill this\n"; 

     sleep($timeToSleep); 

     $i++; 
     close(FILE); 
    } 
    closedir(DIR); 
    #change back to the parent folder 
    chdir("..") or die "Can't change to the directory: $!\n"; 
    print "subRoutine lockFiles success\n"; 
} 

回答

1

我没有安装windows计算机w/perl来检查它是否在那里工作,但Term :: ReadKey上的文档意味着它应该。 Term :: ReadKey是一个提供非阻塞和定时读取功能的模块。它有一些有限的Windows支持。

use Time::HiRes qw(time sleep); 
use Term::ReadKey; 

sub wait_for_key { 
    my $timeout = shift; 

    my $started = time(); 
    while (1) { 
     last if $started + $timeout < time(); 

     my $str = ''; 
     while (my $char = ReadKey(-1)) { 
      $str .= $char; 
     }; 

     last if $str =~ m/\n/s; 
     sleep 0.1; 
    } 
} 

虽然我确信有更好的方法可以做到这一点。也许有人会遇到perl-on-windows体验。

诅咒你,Windows。在任何其他系统上面的代码将如下所示:

sub wait_for_key { ReadLine(shift) } 
+0

抱歉,延迟响应,但它看起来像它的工作。我只是把一个'回报'在内部while循环中,所以当它检测到一个键时,它会退出你的子程序,返回到我的程序并关闭(解锁)文件。谢谢你的帮助。 – iCanHasFay

0

尝试水木清华这样的:

use Sys::SigAction qw(sig_alarm set_sig_handler); 

sub wait_for_key { 
    my $timeout = shift; 

    eval { 
     my $sa = set_sig_handler('ALRM', sub { die "enough" }, {}); 
     eval { 
      sig_alarm($timeout); 
      my $keyboard = <>; 
      sig_alarm(0); 
     }; 
     sig_alarm(0); 
    } 
} 

此功能的输入之后,将退出(“Enter”键),或超时,所以你只需要调用它,而不是睡眠()。其基本思想是:

1)等待无限的输入
2)但设置您需要的超时报警。

看起来邪恶,但工作正常。

这实际上是一种通用的方式来调用一些代码超时 - 只是使这个功能接受第二个参数,这是一个函数参考,并调用该参考,而不是my $keyboard = <>线。并且,检查这些错误,并完成我在此示例中遗漏的所有无聊的内容。

+0

谢谢。我今天会试一试。 – iCanHasFay

+0

这是我没有提及它的错,但是这个脚本将在Windows环境中运行。在查看Sys :: Sigaction CPAN页面时,在MakeFile.pl中,我发现它们不支持Windows。你知道任何其他方法来解决这个问题吗?谢谢。 – iCanHasFay

+0

这不像是“他们不支持windows”,更像是“windows不支持POSIX”。这标志着事物本质上是POSIX-y。 –