Крон (cron) на PHP

Статус
В этой теме нельзя размещать новые ответы.

venetu

Мой дом здесь!
Регистрация
28 Мар 2007
Сообщения
745
Реакции
273
Решил, что это достойно отдельной темы.

Самая главная проблема крона - это то, что он может выполняться несколько раз одновременно. В простейшем варианте мы
1) Проверяем, не наступило ли время
2) Если наступило, выполняем нужные действия
3) Записываем куда-то время следующего запуска

При этом, если выполняются два или более экземпляра скрипта, то второй может вклиниться в тот момент, когда первый уже проверил, что пора выполняться, а новое время еще не сохранил - и в результате пойдут выполняться оба. Для эащиты от такого можно использовать семафоры, или транзакции в mysql, но можно попытаться и проще.
И в любом случае, нам придется где-то хранить время следующего запуска.

Вариант для MySQL
PHP:
  // id=1 - ежедневно в 00:05
  $query = "UPDATE crontab 
	SET   atime = '".date('Y-m-d 00:05:00', time()+24*60*60)."' 
	WHERE atime < '".date('Y-m-d H:i:s')."' AND id=1 LIMIT 1";
  mysql_query($query);
  if (mysql_affected_rows()) {
	// выполняем крон.

  }
Тут мы одним махом проверили время и сразу же его проапдейтили до следующего значения. Встроенный в mysql механизм блокировок гарантирует, что mysql_affected_rows() будет true только у одного экземпляра скрипта. Табличка crontab при этом нужна простейшая, по сути нам надо хранить только DATETIME - время следующего запуска.
Код:
CREATE TABLE crontab (
  id tinyint(3) unsigned NOT NULL auto_increment,
  atime datetime NOT NULL,
  PRIMARY KEY  (id)
)


Но конечно же дергать мускул ради такой задачи пожалуй слишком расточительно. Так что немного покопавшись с файловыми блокировками сделал вариант с хранением в файле:

PHP:
$fp = fopen('cron.daily.txt', 'r+');
$atime = strtotime(fread($fp,20));
if ($atime < time() && flock($fp, LOCK_EX + LOCK_NB)) {
   fseek($fp,0);
   fwrite($fp, date('Y-m-d 00:05:00', time() + 24*60*60)); 
   // выполняем cron

}

Тут по-хорошему файл после записи еще надо транкейтить по новой длине (в нашем случае это не важно, т.к. хранимая в нем дата будет всегда одинаковой длины), анлочить (автоматически анлочится при закрытии хендла) и закрывать (автоматически закрывается при завершении скрипта). Автоматизация рулит.
 
1 Чем не устраивает нормальный cron?
2 На крон не особо тянет, по причине того, что скрипт не может сам по себе вызваться и нет никакой гарантии, что он отработает именно в 00:05
 
Нормальный крон всем устраивает. Нормальный крон в 100 раз лучше такой вот самописной приблуды. Думал, это и так понятно...
 
если на хосте нет крона то всегда можно дёргать с другого сервера скрипты если есть доступ с веб, или использовать бесплатные крон сервисы
 
Помогите реализовать на крон небольшую программу.
Есть число, к которому с каждым месяцем прибавляется постоянная величина.

Т.о. на главной странице выводится это число, и с каждым месяцем оно становится больше на уже известную величину.

Как сделать такую штуку с помощью cron? Или можно ещё как-нибудь?
 
С помощью только крона - никак.
При помощи любого серверного языка - элементарно.
 
Помогите реализовать на крон небольшую программу.
Есть число, к которому с каждым месяцем прибавляется постоянная величина.
Т.о. на главной странице выводится это число, и с каждым месяцем оно становится больше на уже известную величину.
Как сделать такую штуку с помощью cron? Или можно ещё как-нибудь
cron только запускает какие либо задания(например - скрипты), в определенное время.
В вашем случае надо просто настроить cron, так что бы он запускал скрипт раз в месяц. А скрипт уже добавлял эту постоянную величину:)
Хотя, я бы поступил по другому, просто при каждом запросе главной страницы, судя по нынешнему году и месяцу рассчитывал бы то самое число.
 
Хотя, я бы поступил по другому, просто при каждом запросе главной страницы, судя по нынешнему году и месяцу рассчитывал бы то самое число.
Бездумное расточительство ресурсов.
Крон раз в месяц + отдельный скрипт - самое оно.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху