2012-05-14 3 views
0

У меня есть подпрограмма, в которой я пытаюсь заблокировать только один файл (по одному за раз) и удерживать эту блокировку на определенное количество заданного времени (через sleep). Я пытаюсь добавить функциональность, позволяющую пользователю разблокировать текущий заблокированный (спящий) файл всякий раз, когда он нажимает определенный ключ, например клавишу ввода. Я просто не уверен, в каком направлении идти, чтобы заставить это работать. Каждая попытка использования STDIN и проверки на \ n не работала. Благодарю.Блокировка и разблокировка файлов из ввода

Ниже приводится подпрограмма. Я перехожу в каталог, в котором я хочу файлы. Создайте файлы от 1 до количества заданных файлов. Для каждого файла включается исключительная блокировка, затем спит в течение определенного количества времени.

Редактировать: Это моя ошибка в том, что вы не упомянули об этом, но этот скрипт будет запущен в среде Windows. Мне идеально понравилось бы решение, которое не требует дополнительной установки модуля, которые не включены в Perl. (Это было вызвано тем, что модуль в решении breqwas не поддерживает 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

У меня нет оконной машины с 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

Try то вроде этого:

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); 
    } 
} 

Эта функция будет выходить после любого входа («Ввод»), или тайм-аут, так что вы просто назвать его вместо сна(). Основная идея такова:

1) бесконечно ждать ввода
2), но установите будильник для требуемого тайм-аута.

Выглядит злой, но отлично работает.

Это на самом деле общий способ вызова некоторого кода с таймаутом - просто заставьте эту функцию принять второй параметр, который является ссылкой на функцию, и вызовите эту ссылку вместо строки my $keyboard = <>. И, ну, проверьте ошибки и сделайте все скучные вещи, которые я оставил в этом примере.

+0

Спасибо. Сегодня я попробую. – iCanHasFay

+0

Ну, это моя вина не упоминать об этом, но этот скрипт будет запущен в среде Windows. При просмотре страницы CPAN Sys :: Sigaction в MakeFile.pl я обнаружил, что они не поддерживают Windows. Вы знаете какой-либо другой метод решения этой проблемы? Благодарю. – iCanHasFay

+0

Не похоже, что «они не поддерживают окна», это больше похоже на то, что «окна не поддерживают POSIX». Эта сигнальная вещь по своей природе POSIX-y. –

Смежные вопросы