У меня есть программа, которая работает в режиме однократного запуска, но не работает, когда я запускаю ее в фоновом режиме с циклом do-while-true, который включает задержку sleep (60).
if ($debug || $run_once) {check_mail($domain_mail_box, $mailboxes); exit;}
else {
do {
check_mail($domain_mail_box, $mailboxes);
# sleep 60;
# exec('sleep 60'); # wait a minute after completing each run
$i=0; do { $i++; } while ($i < 3000000001);
} while (TRUE);
}
exit(0);
На самом деле, все три попытки заставить его работать должным образом провалились. Это странно, потому что он прекрасно работает на другом сервере / системе. (Оба являются специальными блоками CentOS.)
Ошибка — ошибка MySQL. Как часть сценария, он записывает в журнал. Первый запуск и первый запуск с задержкой записывают что-то вроде этого для mysql_stat ($ Link):
0: Время работы: 605079/1: Темы: 2/2: Вопросы: 17458285/3: Медленные запросы: 0/4: Открытия: 1287520/5: Сброс таблиц: 1/6: Открытые таблицы: 1024/7: Запросы в секунду среднее значение: 28,852 /
но как только я вставляю задержку, я получаю ужас:
0: сервер MySQL ушел /
из mysql_stat.
Есть идеи, что происходит?
Хммм. Я думаю, что нашел некоторую информацию, которая проливает свет на мою проблему: этот комментарий от http://php.net/manual/en/mysqli.close.php. Я рассматриваю проблему, объясненную, если не решенную. Я на самом деле решаю, просто создавая и уничтожая ссылку на БД при каждом запуске программы. Надеюсь, достаточно просто и без особых накладных расходов.
По крайней мере, для PHP5.3.2 и Windows, соединяющихся по tcp, это отличается от старой функции mysql_close () тем, что она фактически не закрывает используемый сокет tcp. Вы должны всегда использовать функцию mysqli_kill () перед mysqli_close (), чтобы фактически закрыть и освободить сокет tcp, используемый PHP. Сборка мусора после выполнения скрипта и mysqli_close () не убивают сокет tcp самостоятельно. В противном случае сокет оставался бы в состоянии ожидания в течение приблизительно 30 секунд, и любые дополнительные загрузки страницы / попытки подключения только добавляли бы к общему количеству открытых соединений tcp. Это время ожидания не настраивается через настройки PHP.
В своем комментарии вы сказали, что хотите использовать таймер для управления синхронизацией данных между выполнением функций.
Cron рабочие места гораздо более надежный подход. То, что вы пытаетесь реализовать, — уродливое решение.
Трюк, который вы должны использовать в вашем случае:
1) Создайте cron, который запускается каждую минуту, и выполняйте логику почты.
2) Добавить таблицу ‘cron_locks’ в базу данных с именем столбца. Когда ваш cron запускается, вы проверяете, есть ли в этой таблице строка по имени.
3) Если блокировка установлена, вы должны пропустить cron. Если блокировка не установлена - установите ее.
4) В конце функции вы снимаете блокировку с БД.
Пожалуйста, спросите меня о дальнейших объяснениях, если я не был достаточно ясен. Я считаю, что это правильное решение вашей проблемы.