Запретить повторный запуск скрипта

govnoproger.ru > php > Запретить повторный запуск скрипта

Иногда бывает так что скрипт который пинает крон не успевает отработать за заданное время, в итоге запускается его копия. А потом возможно вторая копия, третья, четвертая, и так пока не повалит ваш хостинг акк.

Вот собственно способы как этого избежать:

1) Способ для нищих с MYSQL:
Создать поле в базе и туда заносить время. Если разница по времени такая-то, то прерываем скрипт.

Преимущества:Будет работать на большинстве хостингов.
Недостатки:Насилует базу запросами. Неэффективное решение. Скрипт может не точно сработать.

2) Способ со знаменитым flock’ом
Спращивал у техподдержки будет ли работать:

$fh_lock = fopen( 'me.lock', 'w' );
if( ! ( $fh_lock && flock( $fh_lock, LOCK_EX | LOCK_NB ) ) ) die; 

Сказали flock работает только под windows.
Я естественно проверил. Получил предупреждение permission denied.

Преимущества: Хорошо работает.
Недостатков: нету, кроме того что не везде работает.

3) Забиндивание сокета.

Третий способ заключается в открытии порта. Суть в том что если порт уже открыт, то вы получите ошибку, от неё и можно оттолкнуться. Пример:

<?php
ob_implicit_flush();
header("Content-Type: text/plain");
@set_time_limit(60);
error_reporting(E_ALL);

$address = "127.0.0.1";
$port = "12341";

$sock=socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
if (socket_last_error()!=0)
{
	echo socket_last_error(socket_last_error())." не создать \n";
	die;
}
for ($i=0;$i<10;$i++)
{
	echo "ok \n";
	usleep(100);
}


socket_bind($sock, $address, $port);
if (socket_last_error()!=0)
{
	echo socket_last_error(socket_last_error())." занят \n";
	die;
}

sleep(10);
socket_close($sock);
echo "готово \n";

?>

Преимущества: Работает, и стабильно причем.
Недостатки:Требует расширение низкоуровневых сокетов. У большинства их просто нету, как и у вас скорее всего 🙂

Рекомендую:

7.12.2010 | последняя редакция: 07.12.2010 |
  1. xyz
    23.3.2011 в 11:37

    Аффтор, ну ты отжог … Особенно с сокетами, эт п…ц …
    Вот так не судьба?

    //BEGIN
    if (file_get_contents('flag.txt') == 'я работаю') die;
    file_put_contents('flag.txt', 'я работаю');
    // do something
    file_put_contents('flag.txt', 'мне пох');
    //END
    
  2. admin
    23.3.2011 в 13:26

    failed to open stream: Permission denied
    Обломись. На линуксе не работает.
    С сокетами способ работает везде.