Крон (cron) на PHP

Тема в разделе ".:: Готовые решения", создана пользователем venetu, 2 мар 2009.

Статус темы:
Закрыта.
  1. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Решил, что это достойно отдельной темы.

    Самая главная проблема крона - это то, что он может выполняться несколько раз одновременно. В простейшем варианте мы
    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($fpLOCK_EX LOCK_NB)) {
       
    fseek($fp,0);
       
    fwrite($fpdate('Y-m-d 00:05:00'time() + 24*60*60)); 
       
    // выполняем cron

    }
    Тут по-хорошему файл после записи еще надо транкейтить по новой длине (в нашем случае это не важно, т.к. хранимая в нем дата будет всегда одинаковой длины), анлочить (автоматически анлочится при закрытии хендла) и закрывать (автоматически закрывается при завершении скрипта). Автоматизация рулит.
     
    ndmitry и Псевдоним нравится это.
  2. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    591
    1 Чем не устраивает нормальный cron?
    2 На крон не особо тянет, по причине того, что скрипт не может сам по себе вызваться и нет никакой гарантии, что он отработает именно в 00:05
     
  3. venetu

    venetu

    Регистр.:
    28 мар 2007
    Сообщения:
    737
    Симпатии:
    263
    Нормальный крон всем устраивает. Нормальный крон в 100 раз лучше такой вот самописной приблуды. Думал, это и так понятно...
     
  4. terkin

    terkin

    Регистр.:
    9 дек 2006
    Сообщения:
    513
    Симпатии:
    162
    если на хосте нет крона то всегда можно дёргать с другого сервера скрипты если есть доступ с веб, или использовать бесплатные крон сервисы
     
  5. Псевдоним

    Псевдоним

    Регистр.:
    23 фев 2009
    Сообщения:
    300
    Симпатии:
    68
    Помогите реализовать на крон небольшую программу.
    Есть число, к которому с каждым месяцем прибавляется постоянная величина.

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

    Как сделать такую штуку с помощью cron? Или можно ещё как-нибудь?
     
  6. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    591
    С помощью только крона - никак.
    При помощи любого серверного языка - элементарно.
     
  7. Ceyce

    Ceyce Постоялец

    Регистр.:
    3 ноя 2008
    Сообщения:
    52
    Симпатии:
    51
    cron только запускает какие либо задания(например - скрипты), в определенное время.
    В вашем случае надо просто настроить cron, так что бы он запускал скрипт раз в месяц. А скрипт уже добавлял эту постоянную величину:)
    Хотя, я бы поступил по другому, просто при каждом запросе главной страницы, судя по нынешнему году и месяцу рассчитывал бы то самое число.
     
  8. Псевдоним

    Псевдоним

    Регистр.:
    23 фев 2009
    Сообщения:
    300
    Симпатии:
    68
    Я впринципе и имел cron+php.
     
  9. PHP_Master

    PHP_Master

    Регистр.:
    3 фев 2008
    Сообщения:
    2.647
    Симпатии:
    591
    Бездумное расточительство ресурсов.
    Крон раз в месяц + отдельный скрипт - самое оно.
     
  10. Псевдоним

    Псевдоним

    Регистр.:
    23 фев 2009
    Сообщения:
    300
    Симпатии:
    68
    Это сложно сделать?

    Сейчас я в ручную правлю главную страницу, переписывая число :)
     
Статус темы:
Закрыта.