powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / (Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
23 сообщений из 23, страница 1 из 1
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38550842
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть скрипт, который нежелательно запускать одновременно более одного раза.
В скрипте есть проверка на такой запуск:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
# Блок фиксации отметки о запуске скрипта, для предотвращения запуска второй копии.
$pidfile=$ps_logpath."pid.txt";
if (-e $pidfile) {
	unless (open(PIDFILE, $pidfile)) {
		#Если найден - то выходим
		open ($ps_file101,">>".$ps_repalllog) || die;
			print $ps_file101 $zver." Find previous PID: ".$oldpid." - exit\n";
			print $ps_file101 $zver." Update FINISH at ".formatdatetime("DD.MM.YYYY hh:mm:ss", time)."\n";
			print $ps_file101 "==============================================================\n";
		close $ps_file101;
		exit(1);
	}
	$oldpid=<PIDFILE>;
	close PIDFILE;
	if ($oldpid > 1 && kill(0,$oldpid)) {
		#Если найден - то выходим
		open ($ps_file101,">>".$ps_repalllog) || die;
			print $ps_file101 $zver." Find previous PID: ".$oldpid." - exit\n";
			print $ps_file101 $zver." Update FINISH at ".formatdatetime("DD.MM.YYYY hh:mm:ss", time)."\n";
			print $ps_file101 "==============================================================\n";
		close $ps_file101;
		exit(1);
	}
}
open(PID, ">$pidfile") or die;
	print PID $$;
close(PID);



Хочу сделать такую проверку лучше и по возможности без временных файлов.
Использую такой код:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
{
  use Fcntl ':flock';
  open my $self, '<', $0 or die "Fail on open self: $!";
  my $locked = flock($self, LOCK_EX | LOCK_NB);
  unless ($locked)
  {
    &log("Скрипт уже запущен, завершаю работу",'*');
    exit(1);
  };
}


Но он почему-то не работает.
Даже если заменить $0 на внешний файл, а режим открытия с '<' на '>' (у меня на отладке Windows, а тут про такой баг писали), все-равно не работает.
Что не так в коде?

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38550858
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.(у меня на отладке Windows, а тут про такой баг писали)
В Unix (FreeBSD), кстати, тоже не работает.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38550883
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На фряхе у меня такое работает:

Код: php
1.
2.
3.
4.
use Fcntl qw(:flock SEEK_END);
my $okfile = "/path/to/file.log"; # имя лог-файла, куда пишет скрипт...
open(OKF, "+>>$okfile") or die "Can't open $okfile: $!\n";
flock(OKF, LOCK_EX | LOCK_NB) or die "Can't flock $okfile: $!\n";
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639029
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Апну тему.
Снова потребовалось проверить, что скрипт не запущен дважды, и желательно без дополнительных файлов.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639033
Фотография ScareCrow
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Апну тему.
Снова потребовалось проверить, что скрипт не запущен дважды, и желательно без дополнительных файлов.

получать список процессов и искать там свой файл.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639076
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В списке процессов будет perl.
Как я определю, какой именно скрипт он исполняет?
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639186
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.и желательно без дополнительных файлов.Да не вопрос. Можно и на сам файл скрипта ставить блокировку.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639295
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так на $0 блокировка почему-то не работает.
На отдельном файле (у меня это лог-файл, открытый в течении работы скрипта) работает.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639808
lightspeed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
может как-то так?

Код: php
1.
2.
defined( my $pid = fork ) or die "Can't fork: $!";
exit if $pid;
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38639934
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что этот код делает, можно прокомментировать?
Я видимо его не совсем понял.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38640435
lightspeed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
использует форк для проверки запущенного инстанса.
и если инстанс уже запущен, либо форк не удался - вываливается.
ставите в начало скрипта, и вперед..
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38640458
Фотография Warstone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lightspeedиспользует форк для проверки запущенного инстанса.
и если инстанс уже запущен, либо форк не удался - вываливается.
ставите в начало скрипта, и вперед..п....ц. Да простят меня модераторы. Орден Дедалла 1-й степени.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38640500
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lightspeedиспользует форк для проверки запущенного инстанса.
А в чем проверка заключается?
Ну форкнется текущий процесс, ну форк тут же закроется.
Как определяется, что параллельно запущен еще один процесс?
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38640727
lightspeed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
эм.. чуваки, не бейте меня сильно. это просто идея и код на вскиду. проверять не локом, к форкать процесс, и проверять статус.
может быть она не верна, но блин, предложите свою тогда.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38641184
Фотография volodin661
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

Sys::RunAlone - make sure only one invocation of a script is active at a time

Код: coco
1.
2.
3.
4.
5.
6.
7.
8.
9.
THEORY OF OPERATION ^

The functionality of this module depends on the availability of the DATA handle in the script from which this module is called (more specifically: in the "main" namespace).

At INIT time, it is checked whethere there is a DATA handle: if not, it exits with an error message on STDERR and an exit value of 2.

If the DATA handle is available, and it cannot be flocked, it exits with an error message on STDERR and an exit value of 1. The error message will be surpressed when silent = 1> was specified in the use statement.

If there is a DATA handle, and it could be flocked, execution continues without any further interference.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38641205
Фотография volodin661
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,
Proc::PID::File - a module to manage process id files

Код: coco
1.
2.
3.
DESCRIPTION ^

This Perl module is useful for writers of daemons and other processes that need to tell whether they are already running, in order to prevent multiple process instances. The module accomplishes this via *nix-style pidfiles, which are files that store a process identifier.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38641284
Фотография Warstone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lightspeedэм.. чуваки, не бейте меня сильно. это просто идея и код на вскиду. проверять не локом, к форкать процесс, и проверять статус.
может быть она не верна, но блин, предложите свою тогда.Скажите, а водите машину вы тоже - управляя рулем с помощью попы?..
А код пишете путем хождения по клаве ногами?

Может это какой-то кодерский абстракционизм...

Давайте тогда и я попробую:

Решать проблему колец и утечек памяти в Перле надо путем использования модуля CGI.pm: h1($var) - сделает ссылку "слабой", в то время как h5(@array) - сделает массив неубиваемым, даже если массив вышел из области видимости.
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38642328
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Так на $0 блокировка почему-то не работает.
На отдельном файле (у меня это лог-файл, открытый в течении работы скрипта) работает.Можно посмотреть Ваш нерабочий пример? У меня блокировка работает, но несколько своеобразно. При попытке запустить второй экземпляр вываливается сообщение такого вида:
Код: php
1.
2.
$ ./test.pl
bash: ./test.pl: /usr/bin/perl: плохой интерпретатор: Текстовый файл занят

В принципе, цель то предотвращения запуска второго экземпляра достинута, хоть и с генерацией ошибки (которую можно при желании отправить в /dev/null).
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38642343
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Так я его в самом начале приводил.
Пробую лочить $0, но блокировка не работает.
Такой код работает:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
open (LAST, '+>:encoding(cp1251)', &getfilename('last')) or die "Can't open log-file for last run!\n";
{
	my $locked = flock(LAST, LOCK_EX | LOCK_NB);
	unless ($locked)
	{
		print TITLE . ' v.' . VERSION . ": Завершение работы: скрипт уже запущен.\n";
		exit(1);
	}
}
...
close(LAST);


Но это у меня в данном примере есть постоянно открытый log-файл.
А я бы хотел решение без дополнительных файлов (используя $0 или секцию _DATA_).
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38642372
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

Прошу прощения, проглядел. Попробую его помусолить.

Мой почти рабочий тестовый пример такой:
Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#!/usr/bin/perl

use strict;
use Fcntl qw(:flock);

print "File for lock: $0\n";
print "Start\n";
open(FL, "+>>$0") or die "Can't open $0: $!\n";
print "Opened\n";
flock(FL, LOCK_EX) or die "Can't flock $0: $!\n";
print "Locked\n";
sleep 20;
print "Exit\n";
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38642551
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот такой тестовый вариант вполне рабочий получился:

Код: php
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
#!/usr/bin/perl

use strict;
use Fcntl qw(:flock);

print "File for lock: $0\n";
print "Start\n";
open(FL, "<$0") or die "Can't open $0: $!\n";
print "Opened\n";
flock(FL, LOCK_EX | LOCK_NB) or die "Can't flock $0: $!\n";
print "Locked\n";
sleep 20;
print "Exit\n";



При запуске второго экземпляра получаю:
Код: php
1.
2.
3.
4.
5.
$ ./test.pl
File for lock: ./test.pl
Start
Opened
Can't flock ./test.pl: Ресурс временно недоступен
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38647888
netwind
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
кстати, почему у вас нигде в скриптах нет намеков на всякий там CGI и тд, но возникает ситуация когда скрипт все же запускают несколько раз?
не нужно чтобы запускался больше одного раза - не запускайте !
...
Рейтинг: 0 / 0
(Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
    #38647920
vkle
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
netwind,

Так проблема второго запуска может возникнуть не только с использованием CGI. У меня как-то аналогичная ситуация возникла при ежеминутном запуске по крону. В нормальных условиях скрипт отрабатывает секунд за 20 и проблем не знал. А когда нагрузка на сервер как-то дико подскочила и скрипт не уложился в предполагаемую минуту - поперли дубликаты на выхлопе. Так и пришлось добавить блокировку.
...
Рейтинг: 0 / 0
23 сообщений из 23, страница 1 из 1
Форумы / PHP, Perl, Python [игнор отключен] [закрыт для гостей] / (Perl) Как проконтроллировать, чтобы был запущен только один инстанс?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]