URL: https://www.opennet.ru/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID3
Нить номер: 4985
[ Назад ]

Исходное сообщение
"Раздел полезных советов: Как создать лок файл на Perl"

Отправлено auto_tips , 20-Янв-05 17:08 
Для защиты от одновременного запуска нескольких процессов, можно сделать так:

my $cfg_glob_lock="/var/run/test.pid";

# Проверяем лок.
if (-f $cfg_glob_lock){
      # Лок присутствует. Проверяем не дохлый ли процесс.
      my $lock_pid = 0;
      open(LOCK,"<$cfg_glob_lock");
      # Если удалось заблокировать, значит процесс мертв.
      my $zombie_lock_flag = flock(LOCK, 2|4);
      $lock_pid = <LOCK>;
      close (LOCK);
      chomp ($lock_pid);
      if ($lock_pid > 0 && $zombie_lock_flag == 0){
          # Реакция на зависший процесс.                                        
          die "Proccess locked (pid=$lock_pid)";
      } else {
          # Лок от мертвого процесса.
          unlink("$cfg_glob_lock");
          warn("DeadLock detected ($lock_pid)");
      }
}    
# Записываем pid в новый лок файл.
open(LOCK,">$cfg_glob_lock");
print LOCK "$$\n";
close(LOCK);
# Открываем лок.
open(GLOB_LOCK,"<$cfg_glob_lock");
flock(GLOB_LOCK, 2);

.... рабочий код скрипта

# Закрываем и удаляем лок
flock(GLOB_LOCK, 8);
close(GLOB_LOCK);
unlink("$cfg_glob_lock");


URL:
Обсуждается: http://www.opennet.ru/tips/info/778.shtml


Содержание

Сообщения в этом обсуждении
"Как создать лок файл на Perl"
Отправлено Сергей , 20-Янв-05 17:08 
А если чужой файл появился в промежутке между
if (-f $cfg_glob_lock){
и
open(LOCK,">$cfg_glob_lock"); ?

man 2 open
/EX

Все другие варианты, к сожалению, нерабочие ;(


"Как создать лок файл на Perl"
Отправлено Maxim Chirkov , 20-Янв-05 23:22 
>А если чужой файл появился в промежутке между
>if (-f $cfg_glob_lock){
>open(LOCK,">$cfg_glob_lock"); ?

Полностью согласен, поправил в контексте использования sysopen(LOCK,$cfg_glob_lock, O_CREAT|O_EXCL|O_WRONLY), можно также вариант блокировки хардлинками привести.

Для борьбы с использованием Race Condition в плане безопасности еще хорошо помогает монтирование world writable разделов с nosymfollow и создание локов/временных файлов в недоступных для посторонних местах.



"Как создать лок файл на Perl"
Отправлено Сергей , 21-Янв-05 09:06 
Ещё (я не зануда ;-):

лучше всё-таки использовать символьные константы O_CREAT и прочие, они от юникса к юниксу отличаются, а мы же боремся за переносимость ;)

И по поводу хардлинков не всё так просто: на монтированных файловых системах, типа той же самбы, их не будет, что приведёт к очевидным проблемам.
Впрочем, вариант с open тоже имеет трудности на некоторых реализациях NFS, но этим, пожалуй, уж точно можно пренебречь.


"Как создать лок файл на Perl"
Отправлено Maxim Chirkov , 21-Янв-05 10:01 
>лучше всё-таки использовать символьные константы O_CREAT и прочие, они от юникса к
>юниксу отличаются, а мы же боремся за переносимость ;)

Поправил.

>И по поводу хардлинков не всё так просто: на монтированных файловых системах,
>типа той же самбы, их не будет, что приведёт к очевидным
>проблемам.
>Впрочем, вариант с open тоже имеет трудности на некоторых реализациях NFS, но
>этим, пожалуй, уж точно можно пренебречь.

А для samba разделов  open лок точно без проблем работает  ? Просто на них тот же File::Find без рукоприкладства ($File::Find::dont_use_nlink=1) неработоспособен.

Впринципе, для локов хардлинками на CPAM есть готовый модуль File::NFSLock.


"Как создать лок файл на Perl"
Отправлено Сергей , 21-Янв-05 15:12 
Да, open точно работает, по крайней мере на C я проверял. Perl тоже должен, обвязка же в итоге сводится к вызову open(2) AFAIK.
Не работает для платформ DOS-OS2-Win, там только через rename, потому что очень сильно зависит от реализации библиотеки, да и в случае хорошей библиотеки нельзя закладываться на это ;-(
Мака под рукой нету, VMS тоже, на них не проверял ;-)

"Как создать лок файл на Perl"
Отправлено Критик , 24-Фев-05 13:50 
Пародон, а чем use Proc::Lock::File; уже устарел???