Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы если она уже запущена, второй копии не было. Читал про семафоры, помогло мало. Под windows писал с использованием мютексов (mutex). Искать уже устал. Подойдет любой пример.
>Есть программа на Perl, которая
> запускается по cron, выполняется долго. Надо, чтобы если она уже запущена, второй копии не было.
> Подойдет любой пример.Я на bash-е открывал на запись лог и проеверял при запуске, занят ли он ещё. Что-то вроде -
#!/bin/bash
LOG=$0.log
lsof "%f" 2>/dev/null >&2 || exit 1
exec >>$LOGecho "Working!"
sleep 60
echo "Done."
>LOG=$0.log
>lsof "%f" 2>/dev/null >&2 || exit 1s/%f/$LOG/
>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>если она уже запущена, второй копии не было. Читал про семафоры,
>помогло мало. Под windows писал с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.как то надобыло реализовать такую фигню срочно, решил проблему так)
при запуске скрипт создовал фаил куда вписивал номер процесса, а в самом конце скрипт удалял этот фаил. При слеедующем запуске шла обычная проверка, существует ли фаил, если да то вычитивается номер процесса из фаила и grep-ится в ps -ef, а если нету фаила то все в порядке.Конечно способ ТАПОРНЫЙ но тогда думать времени не было...
>[оверквотинг удален]
>>уже устал. Подойдет любой пример.
>
>как то надобыло реализовать такую фигню срочно, решил проблему так)
>при запуске скрипт создовал фаил куда вписивал номер процесса, а в самом
>конце скрипт удалял этот фаил. При слеедующем запуске шла обычная проверка,
>существует ли фаил, если да то вычитивается номер процесса из фаила
>и grep-ится в ps -ef, а если нету фаила то все
>в порядке.
>
>Конечно способ ТАПОРНЫЙ но тогда думать времени не было...Я делал так (где-то содрал часть кода):
# check lock file
use Fcntl qw(:flock :DEFAULT);
my $cfg_glob_lock="/tmp/my.lock";
# Проверяем лок.
if (-f $cfg_glob_lock){
# Лок присутствует. Проверяем не дохлый ли процесс.
my $lock_pid = 0;
open(LOCK,"<$cfg_glob_lock");
# Если удалось заблокировать, значит процесс мертв.
my $zombie_lock_flag = flock(LOCK, LOCK_EX|LOCK_NB);
$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 в новый лок файл.
sysopen(LOCK, $cfg_glob_lock, O_CREAT|O_EXCL|O_WRONLY) or die 'Race condition';
print LOCK "$$\n";
close(LOCK);
# Открываем лок.
open(GLOB_LOCK,"<$cfg_glob_lock");
flock(GLOB_LOCK, LOCK_EX);
...
...
...
# Закрываем и удаляем лок
flock(GLOB_LOCK, LOCK_UN);
close(GLOB_LOCK);
unlink("$cfg_glob_lock");
Вот, что у меня получилось:#!/usr/bin/perl -w
use Fcntl ":flock";
use Sys::Syslog;
$lockfilename="/tmp/riseup.lock";
#if (!open(LOCKFILE, ">$lockfilename")) {
print "Can't lock file!";
exit(1);
}
if (!flock(LOCKFILE, LOCK_EX | LOCK_NB)) {
#процесс уже запущен
print "Process already running!" ;
syslog('debug', 'riseup.pl: Process already running!');
exit(1);
}тут нужная такая работа
#
close(LOCKFILE);
unlink($lockfilename);
>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>если она уже запущена, второй копии не было. Читал про семафоры,
>помогло мало. Под windows писал с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.Perl - значит исходник есть. Я бы не стал мудрить, а сделал все через старый как этот мир файл-флаг в /var/run:
1. При запуске проверяешь чтоб файла /var/run/yor_super_proga.pid не существовало
2. Если существует - ругайся и отваливайся
3. Если - нет - создай и положи туда свой PID
4. Перед завершением - файл нужно убить.GR.
>>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>>если она уже запущена, второй копии не было. Читал про семафоры,
>>помогло мало. Под windows писал с использованием мютексов (mutex). Искать
>>уже устал. Подойдет любой пример.Почитай ещё раз про семафоры, а лучше посмотри пример, там нет ничего сложного.
В случаях когда код программы не доступен, но надо обеспечить чтобы выполнялся один экземпляр - есть программа flock. Она блокирует файл (ждёт пока он не освободится), и выполняет указанную программу.
>помогло мало. Под windows писал с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.Посмотри здесь - http://www.cim.mcgill.ca/~franco/OpSys-304-427/messages/node...
А я решил вот так проблему:#!/bin/bash
#esli v processah visit rsync i v komandnoy stroke est kak minimum odno slovo '::upload' to process zapushen i mi vihodim
if ps ax |grep rsync |grep -q ::upload ;
then
exit
elsersync user@123.123.123.123::upload /root/test/
fi
Т.е. процесс запускается с параметрами. Грепим параметр и если находим, т.е. процесс висит в памяти, то выходим :).