Я пытаюсь настроить два отдельных задания cron, которые обращаются к одному и тому же статическому файлу. Одно из заданий запускается каждую минуту, собирая новые данные, поступившие в файл. Второе задание выполняется каждые 30 минут, анализируя агрегированные данные и усекая файл, чтобы сбросить его на следующие 30 минут.
Очевидно, что каждые 30 минут существует вероятность тупика. Есть ли способ написать задание cron для первой задачи, чтобы оно выполнялось только каждую минуту в течение 29 минут (не считая перечисления каждую минуту 1-60, исключая 30 и 60), а затем снова запускалось на 31 минуте? Спасибо!
редактировать
По запросу я использую PHP для выполнения этих операций (поскольку здесь используются некоторые важные структуры данных). Я реализовал использование PHP flock
функция, а пока документация по функциям указывает, что вызов блокируется до тех пор, пока 1) не будет получена блокировка, или 2) LOCK_NB
указана опция, меня смутил тот факт, что следующий пример, кажется, подразумевает, что блокировку можно не получить даже с помощью блокирующего вызова.
Если это не связано с какой-либо другой проблемой (разрешения, прерывания ОС и т. Д.)? Эта проблема блокировки до получения блокировки была действительно мотивацией для моего вопроса, чтобы узнать, есть ли другой способ полностью избежать блокировки файлов, тем самым уменьшая риск неудачной попытки неблокирующей блокировки и остановки скрипта.
Вы не хотите этого делать; единожды, когда ваша работа займет больше минуты, вас обьют из шланга. Подобные гоночные условия создают уродливые проблемы: прерывистые, непредсказуемые и трудно диагностируемые.
Pboin совершенно прав: вам нужно изучить использование семафор в вашем коде, и тогда проблема просто исчезнет, и вам вообще не придется беспокоиться о конфликтах расписания.
На каком языке ты говоришь?
редактировать (извиняюсь за php, какое-то время не использовал его и немного пьян, поэтому может не компилироваться):
«Обычная» тактика с блокировкой состоит в том, чтобы проверить блокировку (что в данном случае я делаю, пытаясь ее получить), и, если она ЕСТЬ, выполнить короткое ожидание и повторить попытку. Вы можете попробовать использовать функцию php sleep () внутри цикла while, например:
while($x){
if(flock($file_handle, LOCK_EX)){
$x = false;
}else{
sleep(5);
$x = true;
}
}
Я использую нечто подобное для множества заданий записи на основе cron. Работает как шарм. На самом деле это метод, аналогичный протоколу связи ALOHA, который очень похож на более поздний сетевой протокол под названием «TCP / IP». Попробуйте, попробуйте и попробуйте еще раз.
Что ж, вы можете занести свои минуты в cron, как вы предлагаете, но это не решает проблему. (Во-первых, cron не гарантирует выполнение в любую минуту.)
Вам, вероятно, будет лучше реализовать некоторые функции блокировки в вашем скрипте - это гораздо меньше взлома. В Расширенное руководство по сценариям Bash, отличный и бесплатный ресурс предлагает lockfile
команда, которая поможет вам в этом.
Если вы все сделаете правильно, у вас будет гораздо меньше проблем.