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

Исходное сообщение
"Определить, что процесс уже запущен"

Отправлено zoonman , 05-Фев-08 15:26 
Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы если она уже запущена, второй копии не было. Читал про семафоры, помогло мало. Под windows писал  с использованием мютексов (mutex). Искать уже устал. Подойдет любой пример.

Содержание

Сообщения в этом обсуждении
"Любой пример"
Отправлено Andrey Mitrofanov , 05-Фев-08 16:31 
>Есть программа на Perl, которая
> запускается по cron, выполняется долго. Надо, чтобы если она уже запущена, второй копии не было.
> Подойдет любой пример.

Я на bash-е открывал на запись лог и проеверял при запуске, занят ли он ещё. Что-то вроде -

#!/bin/bash

LOG=$0.log
lsof "%f" 2>/dev/null >&2 || exit 1
exec >>$LOG

echo "Working!"
sleep 60
echo "Done."


"поторопился"
Отправлено Andrey Mitrofanov , 05-Фев-08 16:32 
>LOG=$0.log
>lsof "%f" 2>/dev/null >&2 || exit 1

s/%f/$LOG/


"Определить, что процесс уже запущен"
Отправлено Arpo , 05-Фев-08 16:32 
>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>если она уже запущена, второй копии не было. Читал про семафоры,
>помогло мало. Под windows писал  с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.

как то надобыло реализовать такую фигню срочно, решил проблему так)
при запуске скрипт создовал фаил куда вписивал номер процесса, а в самом конце скрипт удалял этот фаил. При слеедующем запуске шла обычная проверка, существует ли фаил, если да то вычитивается номер процесса из фаила и grep-ится в ps -ef, а если нету фаила то все в порядке.

Конечно способ ТАПОРНЫЙ но тогда думать времени не было...


"Определить, что процесс уже запущен"
Отправлено Golub Mikhail , 05-Фев-08 16:39 
>[оверквотинг удален]
>>уже устал. Подойдет любой пример.
>
>как то надобыло реализовать такую фигню срочно, решил проблему так)
>при запуске скрипт создовал фаил куда вписивал номер процесса, а в самом
>конце скрипт удалял этот фаил. При слеедующем запуске шла обычная проверка,
>существует ли фаил, если да то вычитивается номер процесса из фаила
>и 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");



"Определить, что процесс уже запущен"
Отправлено zoonman , 07-Фев-08 10:26 
Вот, что у меня получилось:

#!/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);


"Определить, что процесс уже запущен"
Отправлено Аноним , 07-Фев-08 20:47 
>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>если она уже запущена, второй копии не было. Читал про семафоры,
>помогло мало. Под windows писал  с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.

Perl - значит исходник есть. Я бы не стал мудрить, а сделал все через старый как этот мир файл-флаг в /var/run:
1. При запуске проверяешь чтоб файла /var/run/yor_super_proga.pid не существовало
2. Если существует - ругайся и отваливайся
3. Если - нет - создай и положи туда свой PID
4. Перед завершением - файл нужно убить.

GR.


"Определить, что процесс уже запущен"
Отправлено Аноним , 09-Фев-08 17:51 
>>Есть программа на Perl, которая запускается по cron, выполняется долго. Надо, чтобы
>>если она уже запущена, второй копии не было. Читал про семафоры,
>>помогло мало. Под windows писал  с использованием мютексов (mutex). Искать
>>уже устал. Подойдет любой пример.

Почитай ещё раз про семафоры, а лучше посмотри пример, там нет ничего сложного.

В случаях когда код программы не доступен, но надо обеспечить чтобы выполнялся один экземпляр - есть программа flock. Она блокирует файл (ждёт пока он не освободится), и выполняет указанную программу.


"Определить, что процесс уже запущен"
Отправлено ACCA , 08-Мрт-08 07:59 
>помогло мало. Под windows писал  с использованием мютексов (mutex). Искать
>уже устал. Подойдет любой пример.

Посмотри здесь - http://www.cim.mcgill.ca/~franco/OpSys-304-427/messages/node...


"Определить, что процесс уже запущен"
Отправлено tos , 20-Май-09 10:16 
А я решил вот так проблему:

#!/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
  else

rsync  user@123.123.123.123::upload /root/test/

  fi

Т.е. процесс запускается с параметрами. Грепим параметр и если находим, т.е. процесс висит в памяти, то выходим :).