我有一个子程序,其中我试图独占锁定一组文件(一次一个)并保持该锁定一定的给定时间(通过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";
}
答案 0 :(得分:1)
我没有安装带有Perl的Windows机器来检查它是否有效,但是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) }
答案 1 :(得分: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”键)或超时后退出,因此您只需调用它而不是sleep()。基本思路是:
1)无限等待输入
2)但是为你需要的超时设置一个警报。
看起来很邪恶,但工作正常。
这实际上是一种通过超时调用某些代码的通用方法 - 只需使此函数接受第二个参数即函数引用,并调用该引用而不是my $keyboard = <>
行。而且,检查错误并完成我在此示例中遗漏的所有无聊内容。