Запрет параллельного выполнения

Vin-Diesel

Новичок
Запрет параллельного выполнения

Нужно запретить параллельное выполнение скрипта

Пишу "демона" на php, нужно запретить открытие более одной копии скрипта. Есть готовые решения? Спасибо
 

tz-lom

Продвинутый новичок
"готовое решение" - ставить блокировку файлом
 

Vin-Diesel

Новичок
Скрипт:
1. Проверяем наличие файла х, проверяем залочен ли
2. Если да завершаем работу
3. Если нет, создаем, лочит
4. Работаем

В целом алгоритм верный?
 

A1x

Новичок
достаточно одного факта наличия/отсутствия файла
 

Farsh

~ on ~ high ~ wave ~
A1x
А если скрипт неудачно завершил работу, не удалив созданный файл ?
 

Crys

Двинутый новичок
Мне такое же под виндой надо было сегодня.. В общем, сначала час помучился с таск-шедулером - он скрипт запускал, но почему-то работал минуты две-три только, чего было недостаточно. В итоге поставил FireDaemon, запустил как сервис - все, финиш. Если будет ошибка - перезапустится... можно команды по ошибке задавать и т.д. Никаких параллельных запусков нету. Полдня - полет нормальный, утечек памяти не наблюдается.
И ни одной дополнительной строчки кода :)

Думаю, что под линух тоже подобное должно быть. То есть - смысл не в том, чтобы написать демона на php, а в том, чтобы запустить готового демона, который умеет запускать скрипты на php :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
я сделал так:
* запускаю управляющий скрипт из крона, который запускает демоны с параметром --pid-file
* демоны пишут pid-файл и touch() его периодически
* у демона висит хендлер на USR1, который обновляет pid-файл
* управляющий скрипт смотрит mtime pid-файлов, если больше X - делает kill USR1 и если процесса нет - запускает его
* управляющий скрипт ждет N секунд и еще раз проверяет mtime
* если демон не обнови pid-файл - он зомби, и управляющий скрипт его прибивает SIGTERM-ом и запускает заново

могу выложить код

-~{}~ 26.07.10 00:46:

Posix only (no win)
 

A1x

Новичок
A1x
А если скрипт неудачно завершил работу, не удалив созданный файл ?
обычно проверял время от создания файла - если больше какого-то - файл считаем "недействительным"
 

A1x

Новичок
для демона можно периодически делать touch и проверять время модификации
мне было непонятно зачем лочить
 

Vin-Diesel

Новичок
Да проще помоему залочить.

-~{}~ 26.07.10 19:33:

Реализуется проще
PHP:
function Work($path) {
 static $activityFile;
 if($activityFile)
  return;
 $activityFile = fopen($path, 'w');
 if(!flock($activityFile, LOCK_EX | LOCK_NB))
  trigger_error('Script is a working', E_USER_ERROR);
}
#Work('./active');
 

Dovg

Продвинутый новичок
Есть же готовое решение, которое используют все
man start-stop-daemon
у нас нас несколько самописных демонов на php через него запускаются живут, и погибают по просьбе.
Ни единого разрыва ;)

Вообще в теории может быть запущено несколько копий демона с разными параметрами.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
похоже, start-stop-daemon - это скрипт debian, в RH-family его нет
 

Dovg

Продвинутый новичок
в моей генте пишут так:
HISTORY
start-stop-daemon first appeared in Debian.

This is a complete re-implementation with the process finding code in the OpenRC library (librc, -lrc) so other programs can make use of it.
 

clanth

Новичок
Не проще - стандартная логика работы pid файлов для *никсов?
Решает и проблему второго запуска, и если предыдущий демон не удалил файл
PHP:
$pid_file = '/tmp/phpdeamon.pid';
if( is_file($pid_file) ) {
	$pid = file_get_contents($pid_file);
	if (posix_kill($pid,0)) {
		echo "Daemon already active\n";
		return false;
	} else {
		if(!unlink($pid_file)) {
			echo "No access to PID file\n";
			return false;
		}
	}
}
//fork и т.п.
file_put_contents($pid_file, getmypid());
 

fixxxer

К.О.
Партнер клуба
//fork и т.п.

Вот с "т.п." и проблемы - в php нету dup/dup2.
Я решаю через proc_open но это же ужас-ужас.

Вообще runit решает кучу проблем и все сразу. Знал бы о нем сразу, не изобретал бы велосипед.
 

weregod

unserializer
если тему переименовать в "запрет повторного запуска скрипта, пока исполняется предыдущий", то решения без runit можно построить, к тому же кроссплатформенность runit-ом не решается, или я чо-то п?
 
Сверху